From b0486bfabed7ead7b7d5c58a9f9a2aaf6aee2bac Mon Sep 17 00:00:00 2001 From: Pim Pronk Date: Wed, 9 Nov 2016 16:19:20 +0100 Subject: [PATCH] Improved tile support with multiple monitors --- src/client.c | 49 ++++++++++++++++++++++++++++++++++++----- src/screen.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/screen.h | 8 +++++++ 3 files changed, 123 insertions(+), 6 deletions(-) diff --git a/src/client.c b/src/client.c index 668c11b..3c3fcad 100644 --- a/src/client.c +++ b/src/client.c @@ -3271,6 +3271,8 @@ clientNewTileSize (Client *c, XWindowChanges *wc, GdkRectangle *rect, tilePositi rect->y + rect->height) - full_y; clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h); +DBG("full_x = %d", full_x); + switch (tile) { case TILE_UP: @@ -3451,8 +3453,9 @@ clientTile (Client *c, gint cx, gint cy, tilePositionType tile, gboolean send_co DisplayInfo *display_info; ScreenInfo *screen_info; XWindowChanges wc; - GdkRectangle rect; + GdkRectangle rect, rect_prev; unsigned long old_flags; + gboolean window_changed; g_return_val_if_fail (c != NULL, FALSE); @@ -3487,10 +3490,46 @@ clientTile (Client *c, gint cx, gint cy, tilePositionType tile, gboolean send_co } FLAG_SET (c->flags, CLIENT_FLAG_RESTORE_SIZE_POS); - c->x = wc.x; - c->y = wc.y; - c->height = wc.height; - c->width = wc.width; + window_changed = FALSE; + + if ((c->x == wc.x) && (c->width == wc.width) && + (c->y == wc.y) && (c->height == wc.height)) + { + if ((tile == TILE_LEFT)) + { + if (myScreenFindPreviousMonitorForPoint (screen_info, cx, cy, &rect_prev)) + { + clientNewTileSize(c, &wc, &rect_prev, TILE_RIGHT); + } + else + { + clientRestoreSizePos (c); + + window_changed = TRUE; + } + } + else if ((tile == TILE_RIGHT)) + { + if (myScreenFindNextMonitorForPoint (screen_info, cx, cy, &rect_prev)) + { + clientNewTileSize(c, &wc, &rect_prev, TILE_LEFT); + } + else + { + clientRestoreSizePos (c); + + window_changed = TRUE; + } + } + } + + if (!window_changed) + { + c->x = wc.x; + c->y = wc.y; + c->height = wc.height; + c->width = wc.width; + } if (send_configure) { diff --git a/src/screen.c b/src/screen.c index d5c7266..a335b69 100644 --- a/src/screen.c +++ b/src/screen.c @@ -754,6 +754,76 @@ myScreenInvalidateMonitorCache (ScreenInfo *screen_info) screen_info->cache_monitor.height = 0; } +gboolean +myScreenFindPreviousMonitorForPoint(ScreenInfo *screen_info, gint x, gint y, GdkRectangle *rect) +{ + gint num_monitors, i; + GdkRectangle monitor, current_monitor = { G_MAXINT, G_MAXINT, 0, 0 }; + + g_return_if_fail (screen_info != NULL); + g_return_if_fail (rect != NULL); + g_return_if_fail (GDK_IS_SCREEN (screen_info->gscr)); + TRACE ("entering myScreenFindPreviousMonitorForPoint"); + + + myScreenFindMonitorAtPoint (screen_info, x, y, ¤t_monitor); + + num_monitors = myScreenGetNumMonitors (screen_info); + + for (i = 0; i < (num_monitors - 1); i++) + { + gint monitor_index; + + monitor_index = myScreenGetMonitorIndex (screen_info, i + 1); + gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_index, &monitor); + + if ((monitor.x == current_monitor.x) && (monitor.y == current_monitor.y)) + { + monitor_index = myScreenGetMonitorIndex (screen_info, i); + gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_index, &monitor); + *rect = monitor; + return TRUE; + } + } + + return FALSE; +} + +gboolean +myScreenFindNextMonitorForPoint(ScreenInfo *screen_info, gint x, gint y, GdkRectangle *rect) +{ + gint num_monitors, i; + GdkRectangle monitor, current_monitor = { G_MAXINT, G_MAXINT, 0, 0 }; + + g_return_if_fail (screen_info != NULL); + g_return_if_fail (rect != NULL); + g_return_if_fail (GDK_IS_SCREEN (screen_info->gscr)); + TRACE ("entering myScreenFindNextMonitorForPoint"); + + + myScreenFindMonitorAtPoint (screen_info, x, y, ¤t_monitor); + + num_monitors = myScreenGetNumMonitors (screen_info); + + for (i = 1; i < num_monitors; i++) + { + gint monitor_index; + + monitor_index = myScreenGetMonitorIndex (screen_info, i - 1); + gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_index, &monitor); + + if ((monitor.x == current_monitor.x) && (monitor.y == current_monitor.y)) + { + monitor_index = myScreenGetMonitorIndex (screen_info, i); + gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_index, &monitor); + *rect = monitor; + return TRUE; + } + } + + return FALSE; +} + /* gdk_screen_get_monitor_at_point () doesn't give accurate results when the point is off screen, use my own implementation from xfce 3 @@ -787,7 +857,7 @@ myScreenFindMonitorAtPoint (ScreenInfo *screen_info, gint x, gint y, GdkRectangl monitor_index = myScreenGetMonitorIndex (screen_info, i); gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_index, &monitor); - + if ((x >= monitor.x) && (x < (monitor.x + monitor.width)) && (y >= monitor.y) && (y < (monitor.y + monitor.height))) { diff --git a/src/screen.h b/src/screen.h index 2f19057..0655291 100644 --- a/src/screen.h +++ b/src/screen.h @@ -269,6 +269,14 @@ gint myScreenGetMonitorIndex (ScreenInfo *, gint); gboolean myScreenRebuildMonitorIndex (ScreenInfo *); void myScreenInvalidateMonitorCache (ScreenInfo *); +gboolean myScreenFindPreviousMonitorForPoint (ScreenInfo *, + gint, + gint, + GdkRectangle *); +gboolean myScreenFindNextMonitorForPoint (ScreenInfo *, + gint, + gint, + GdkRectangle *); void myScreenFindMonitorAtPoint (ScreenInfo *, gint, gint, -- 2.7.4