Bugfix: Correctly do boundary checking/moving to other workspaces when moving floating clients via keyboard (Thanks sasha)
This commit is contained in:
parent
0b6b8e8380
commit
87f8c501da
|
@ -78,6 +78,12 @@ enum {
|
||||||
* It needs to be packed so that the compiler will not add any padding bytes.
|
* It needs to be packed so that the compiler will not add any padding bytes.
|
||||||
* (it is used in src/ewmh.c for example)
|
* (it is used in src/ewmh.c for example)
|
||||||
*
|
*
|
||||||
|
* Note that x and y can contain signed values in some cases (for example when
|
||||||
|
* used for the coordinates of a window, which can be set outside of the
|
||||||
|
* visible area, but not when specifying the position of a workspace for the
|
||||||
|
* _NET_WM_WORKAREA hint). Not declaring x/y as int32_t saves us a lot of
|
||||||
|
* typecasts.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
struct Rect {
|
struct Rect {
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
|
|
@ -411,28 +411,37 @@ void floating_focus_direction(xcb_connection_t *conn, Client *currently_focused,
|
||||||
void floating_move(xcb_connection_t *conn, Client *currently_focused, direction_t direction) {
|
void floating_move(xcb_connection_t *conn, Client *currently_focused, direction_t direction) {
|
||||||
DLOG("floating move\n");
|
DLOG("floating move\n");
|
||||||
|
|
||||||
|
Rect destination = currently_focused->rect;
|
||||||
|
Rect *screen = &(currently_focused->workspace->screen->rect);
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case D_LEFT:
|
case D_LEFT:
|
||||||
if (currently_focused->rect.x < 10)
|
destination.x -= 10;
|
||||||
return;
|
|
||||||
currently_focused->rect.x -= 10;
|
|
||||||
break;
|
break;
|
||||||
case D_RIGHT:
|
case D_RIGHT:
|
||||||
currently_focused->rect.x += 10;
|
destination.x += 10;
|
||||||
break;
|
break;
|
||||||
case D_UP:
|
case D_UP:
|
||||||
if (currently_focused->rect.y < 10)
|
destination.y -= 10;
|
||||||
return;
|
|
||||||
currently_focused->rect.y -= 10;
|
|
||||||
break;
|
break;
|
||||||
case D_DOWN:
|
case D_DOWN:
|
||||||
currently_focused->rect.y += 10;
|
destination.y += 10;
|
||||||
break;
|
break;
|
||||||
/* to make static analyzers happy */
|
/* to make static analyzers happy */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent windows from vanishing completely */
|
||||||
|
if ((int32_t)(destination.x + destination.width - 5) <= (int32_t)screen->x ||
|
||||||
|
(int32_t)(destination.x + 5) >= (int32_t)(screen->x + screen->width) ||
|
||||||
|
(int32_t)(destination.y + destination.height - 5) <= (int32_t)screen->y ||
|
||||||
|
(int32_t)(destination.y + 5) >= (int32_t)(screen->y + screen->height)) {
|
||||||
|
DLOG("boundary check failed, not moving\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currently_focused->rect = destination;
|
||||||
reposition_client(conn, currently_focused);
|
reposition_client(conn, currently_focused);
|
||||||
|
|
||||||
/* Because reposition_client does not send a faked configure event (only resize does),
|
/* Because reposition_client does not send a faked configure event (only resize does),
|
||||||
|
|
|
@ -228,7 +228,9 @@ void reposition_client(xcb_connection_t *conn, Client *client) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If the client is floating, we need to check if we moved it to a different workspace */
|
/* If the client is floating, we need to check if we moved it to a different workspace */
|
||||||
if (client->workspace->screen == (screen = get_screen_containing(client->rect.x, client->rect.y)))
|
screen = get_screen_containing(client->rect.x + (client->rect.width / 2),
|
||||||
|
client->rect.y + (client->rect.height / 2));
|
||||||
|
if (client->workspace->screen == screen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (screen == NULL) {
|
if (screen == NULL) {
|
||||||
|
@ -239,6 +241,8 @@ void reposition_client(xcb_connection_t *conn, Client *client) {
|
||||||
DLOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen);
|
DLOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen);
|
||||||
DLOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen);
|
DLOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen);
|
||||||
floating_assign_to_workspace(client, screen->current_workspace);
|
floating_assign_to_workspace(client, screen->current_workspace);
|
||||||
|
|
||||||
|
set_focus(conn, client, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue