/**
* Stores a rectangle, for example the size of a window, the child window etc.
*
+ * 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 {
uint32_t x, y;
void floating_move(xcb_connection_t *conn, Client *currently_focused, direction_t direction) {
LOG("floating move\n");
+ Rect destination = currently_focused->rect;
+ Rect *screen = &(currently_focused->workspace->screen->rect);
+
switch (direction) {
case D_LEFT:
- if (currently_focused->rect.x < 10)
- return;
- currently_focused->rect.x -= 10;
+ destination.x -= 10;
break;
case D_RIGHT:
- currently_focused->rect.x += 10;
+ destination.x += 10;
break;
case D_UP:
- if (currently_focused->rect.y < 10)
- return;
- currently_focused->rect.y -= 10;
+ destination.y -= 10;
break;
case D_DOWN:
- currently_focused->rect.y += 10;
+ destination.y += 10;
break;
/* to make static analyzers happy */
default:
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);
/* Because reposition_client does not send a faked configure event (only resize does),
return;
/* 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;
if (screen == NULL) {
LOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen);
LOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen);
floating_assign_to_workspace(client, screen->current_workspace);
+
+ set_focus(conn, client, true);
}
/*