Bugfix: Correctly handle moving fullscreen client onto another screen (Thanks dirkson)
This commit is contained in:
parent
aa2f20ce26
commit
8659419ef6
|
@ -44,6 +44,13 @@ void client_kill(xcb_connection_t *conn, Client *window);
|
|||
bool client_matches_class_name(Client *client, char *to_class, char *to_title,
|
||||
char *to_title_ucs, int to_title_ucs_len);
|
||||
|
||||
/**
|
||||
* Enters fullscreen mode for the given client. This is called by toggle_fullscreen
|
||||
* and when moving a fullscreen client to another screen.
|
||||
*
|
||||
*/
|
||||
void client_enter_fullscreen(xcb_connection_t *conn, Client *client);
|
||||
|
||||
/**
|
||||
* Toggles fullscreen mode for the given client. It updates the data structures and
|
||||
* reconfigures (= resizes/moves) the client and its frame to the full size of the
|
||||
|
|
117
src/client.c
117
src/client.c
|
@ -136,6 +136,53 @@ bool client_matches_class_name(Client *client, char *to_class, char *to_title,
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enters fullscreen mode for the given client. This is called by toggle_fullscreen
|
||||
* and when moving a fullscreen client to another screen.
|
||||
*
|
||||
*/
|
||||
void client_enter_fullscreen(xcb_connection_t *conn, Client *client) {
|
||||
Workspace *workspace = client->workspace;
|
||||
|
||||
if (workspace->fullscreen_client != NULL) {
|
||||
LOG("Not entering fullscreen mode, there already is a fullscreen client.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
client->fullscreen = true;
|
||||
workspace->fullscreen_client = client;
|
||||
LOG("Entering fullscreen mode...\n");
|
||||
/* We just entered fullscreen mode, let’s configure the window */
|
||||
uint32_t mask = XCB_CONFIG_WINDOW_X |
|
||||
XCB_CONFIG_WINDOW_Y |
|
||||
XCB_CONFIG_WINDOW_WIDTH |
|
||||
XCB_CONFIG_WINDOW_HEIGHT;
|
||||
uint32_t values[4] = {workspace->rect.x,
|
||||
workspace->rect.y,
|
||||
workspace->rect.width,
|
||||
workspace->rect.height};
|
||||
|
||||
LOG("child itself will be at %dx%d with size %dx%d\n",
|
||||
values[0], values[1], values[2], values[3]);
|
||||
|
||||
xcb_configure_window(conn, client->frame, mask, values);
|
||||
|
||||
/* Child’s coordinates are relative to the parent (=frame) */
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
xcb_configure_window(conn, client->child, mask, values);
|
||||
|
||||
/* Raise the window */
|
||||
values[0] = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
|
||||
Rect child_rect = workspace->rect;
|
||||
child_rect.x = child_rect.y = 0;
|
||||
fake_configure_notify(conn, child_rect, client->child);
|
||||
|
||||
xcb_flush(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Toggles fullscreen mode for the given client. It updates the data structures and
|
||||
* reconfigures (= resizes/moves) the client and its frame to the full size of the
|
||||
|
@ -149,60 +196,28 @@ void client_toggle_fullscreen(xcb_connection_t *conn, Client *client) {
|
|||
Workspace *workspace = client->workspace;
|
||||
|
||||
if (!client->fullscreen) {
|
||||
if (workspace->fullscreen_client != NULL) {
|
||||
LOG("Not entering fullscreen mode, there already is a fullscreen client.\n");
|
||||
return;
|
||||
}
|
||||
client->fullscreen = true;
|
||||
workspace->fullscreen_client = client;
|
||||
LOG("Entering fullscreen mode...\n");
|
||||
/* We just entered fullscreen mode, let’s configure the window */
|
||||
uint32_t mask = XCB_CONFIG_WINDOW_X |
|
||||
XCB_CONFIG_WINDOW_Y |
|
||||
XCB_CONFIG_WINDOW_WIDTH |
|
||||
XCB_CONFIG_WINDOW_HEIGHT;
|
||||
uint32_t values[4] = {workspace->rect.x,
|
||||
workspace->rect.y,
|
||||
workspace->rect.width,
|
||||
workspace->rect.height};
|
||||
client_enter_fullscreen(conn, client);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("child itself will be at %dx%d with size %dx%d\n",
|
||||
values[0], values[1], values[2], values[3]);
|
||||
|
||||
xcb_configure_window(conn, client->frame, mask, values);
|
||||
|
||||
/* Child’s coordinates are relative to the parent (=frame) */
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
xcb_configure_window(conn, client->child, mask, values);
|
||||
|
||||
/* Raise the window */
|
||||
values[0] = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
|
||||
Rect child_rect = workspace->rect;
|
||||
child_rect.x = child_rect.y = 0;
|
||||
fake_configure_notify(conn, child_rect, client->child);
|
||||
LOG("leaving fullscreen mode\n");
|
||||
client->fullscreen = false;
|
||||
workspace->fullscreen_client = NULL;
|
||||
if (client_is_floating(client)) {
|
||||
/* For floating clients it’s enough if we just reconfigure that window (in fact,
|
||||
* re-rendering the layout will not update the client.) */
|
||||
reposition_client(conn, client);
|
||||
resize_client(conn, client);
|
||||
/* redecorate_window flushes */
|
||||
redecorate_window(conn, client);
|
||||
} else {
|
||||
LOG("leaving fullscreen mode\n");
|
||||
client->fullscreen = false;
|
||||
workspace->fullscreen_client = NULL;
|
||||
if (client_is_floating(client)) {
|
||||
/* For floating clients it’s enough if we just reconfigure that window (in fact,
|
||||
* re-rendering the layout will not update the client.) */
|
||||
reposition_client(conn, client);
|
||||
resize_client(conn, client);
|
||||
/* redecorate_window flushes */
|
||||
redecorate_window(conn, client);
|
||||
} else {
|
||||
client_set_below_floating(conn, client);
|
||||
client_set_below_floating(conn, client);
|
||||
|
||||
/* Because the coordinates of the window haven’t changed, it would not be
|
||||
re-configured if we don’t set the following flag */
|
||||
client->force_reconfigure = true;
|
||||
/* We left fullscreen mode, redraw the whole layout to ensure enternotify events are disabled */
|
||||
render_layout(conn);
|
||||
}
|
||||
/* Because the coordinates of the window haven’t changed, it would not be
|
||||
re-configured if we don’t set the following flag */
|
||||
client->force_reconfigure = true;
|
||||
/* We left fullscreen mode, redraw the whole layout to ensure enternotify events are disabled */
|
||||
render_layout(conn);
|
||||
}
|
||||
|
||||
xcb_flush(conn);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "xinerama.h"
|
||||
#include "client.h"
|
||||
#include "floating.h"
|
||||
#include "xcb.h"
|
||||
|
||||
bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction) {
|
||||
/* If this container is empty, we’re done */
|
||||
|
@ -559,8 +560,6 @@ static void move_current_window_to_workspace(xcb_connection_t *conn, int workspa
|
|||
CIRCLEQ_INSERT_TAIL(&(to_container->clients), current_client, clients);
|
||||
|
||||
SLIST_INSERT_HEAD(&(to_container->workspace->focus_stack), current_client, focus_clients);
|
||||
if (current_client->fullscreen)
|
||||
t_ws->fullscreen_client = current_client;
|
||||
LOG("Moved.\n");
|
||||
|
||||
current_client->container = to_container;
|
||||
|
@ -568,16 +567,26 @@ static void move_current_window_to_workspace(xcb_connection_t *conn, int workspa
|
|||
container->currently_focused = to_focus;
|
||||
to_container->currently_focused = current_client;
|
||||
|
||||
bool target_invisible = (to_container->workspace->screen->current_workspace != to_container->workspace->num);
|
||||
|
||||
/* If we’re moving it to an invisible screen, we need to unmap it */
|
||||
if (to_container->workspace->screen->current_workspace != to_container->workspace->num) {
|
||||
if (target_invisible) {
|
||||
LOG("This workspace is not visible, unmapping\n");
|
||||
xcb_unmap_window(conn, current_client->frame);
|
||||
} else {
|
||||
if (current_client->fullscreen) {
|
||||
LOG("Calling client_enter_fullscreen again\n");
|
||||
client_enter_fullscreen(conn, current_client);
|
||||
}
|
||||
}
|
||||
|
||||
/* delete all empty columns/rows */
|
||||
cleanup_table(conn, container->workspace);
|
||||
|
||||
render_layout(conn);
|
||||
|
||||
if (!target_invisible)
|
||||
set_focus(conn, current_client, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue