From 138eb1e3b4be10552274688282c7892385ce47b5 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sat, 8 Oct 2011 11:00:16 -0400 Subject: [PATCH] tiling: keep track of the monitor where a window was tiled meta_window_get_current_tile_area() computes the area where the tiled window should be based on the current pointer position but that's only meaningful when the user is actually dragging the window. When running the tiling constrain the pointer might be on other monitor and at that point the window jumps to this other monitor. https://bugzilla.gnome.org/show_bug.cgi?id=642580 --- src/core/display-private.h | 1 + src/core/display.c | 12 ++++++++++-- src/core/keybindings.c | 1 + src/core/window-private.h | 1 + src/core/window.c | 33 ++++++++++++++++++++++++--------- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 6d9d648ee..3950065cd 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -189,6 +189,7 @@ struct _MetaDisplay int grab_anchor_root_y; MetaRectangle grab_anchor_window_pos; MetaTileMode grab_tile_mode; + int grab_tile_monitor_number; int grab_latest_motion_x; int grab_latest_motion_y; gulong grab_mask; diff --git a/src/core/display.c b/src/core/display.c index 891004429..85cdd16aa 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -554,6 +554,7 @@ meta_display_open (void) the_display->grab_screen = NULL; the_display->grab_resize_popup = NULL; the_display->grab_tile_mode = META_TILE_NONE; + the_display->grab_tile_monitor_number = -1; the_display->grab_edge_resistance_data = NULL; @@ -3593,9 +3594,15 @@ meta_display_begin_grab_op (MetaDisplay *display, display->grab_button = button; display->grab_mask = modmask; if (window) - display->grab_tile_mode = window->tile_mode; + { + display->grab_tile_mode = window->tile_mode; + display->grab_tile_monitor_number = window->tile_monitor_number; + } else - display->grab_tile_mode = META_TILE_NONE; + { + display->grab_tile_mode = META_TILE_NONE; + display->grab_tile_monitor_number = -1; + } display->grab_anchor_root_x = root_x; display->grab_anchor_root_y = root_y; display->grab_latest_motion_x = root_x; @@ -3793,6 +3800,7 @@ meta_display_end_grab_op (MetaDisplay *display, display->grab_screen = NULL; display->grab_xwindow = None; display->grab_tile_mode = META_TILE_NONE; + display->grab_tile_monitor_number = -1; display->grab_op = META_GRAB_OP_NONE; if (display->grab_resize_popup) diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 0e7d355fc..8c5cb42bf 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1612,6 +1612,7 @@ process_mouse_move_resize_grab (MetaDisplay *display, /* Restore the original tile mode */ window->tile_mode = display->grab_tile_mode; + window->tile_monitor_number = display->grab_tile_monitor_number; /* End move or resize and restore to original state. If the * window was a maximized window that had been "shaken loose" we diff --git a/src/core/window-private.h b/src/core/window-private.h index 8a5fd6258..55afdde16 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -129,6 +129,7 @@ struct _MetaWindow * this is the current mode. If not, it is the mode which will be * requested after the window grab is released */ guint tile_mode : 2; + int tile_monitor_number; /* Whether we're shaded */ guint shaded : 1; diff --git a/src/core/window.c b/src/core/window.c index 6a574b08d..6dd907f5e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -965,6 +965,7 @@ meta_window_new_with_attrs (MetaDisplay *display, window->on_all_workspaces = FALSE; window->on_all_workspaces_requested = FALSE; window->tile_mode = META_TILE_NONE; + window->tile_monitor_number = -1; window->shaded = FALSE; window->initially_iconic = FALSE; window->minimized = FALSE; @@ -4358,6 +4359,9 @@ meta_window_update_for_monitors_changed (MetaWindow *window) } } + if (window->tile_mode != META_TILE_NONE) + window->tile_monitor_number = new->number; + /* This will eventually reach meta_window_update_monitor that * will send leave/enter-monitor events. The old != new monitor * check will always fail (due to the new monitor_infos set) so @@ -5016,6 +5020,9 @@ meta_window_move_to_monitor (MetaWindow *window, monitor, &new_area); + if (window->tile_mode != META_TILE_NONE) + window->tile_monitor_number = monitor; + meta_window_move_between_rects (window, &old_area, &new_area); } @@ -8431,11 +8438,15 @@ update_move (MetaWindow *window, /* For side-by-side tiling we are interested in the inside vertical * edges of the work area of the monitor where the pointer is located, * and in the outside top edge for maximized tiling. - * Also see comment in meta_window_get_current_tile_area(). * * For maximized tiling we use the outside edge instead of the * inside edge, because we don't want to force users to maximize * windows they are placing near the top of their screens. + * + * The "current" idea of meta_window_get_work_area_current_monitor() and + * meta_screen_get_current_monitor() is slightly different: the former + * refers to the monitor which contains the largest part of the window, + * the latter to the one where the pointer is located. */ monitor = meta_screen_get_current_monitor (window->screen); meta_window_get_work_area_for_monitor (window, @@ -8457,6 +8468,9 @@ update_move (MetaWindow *window, window->tile_mode = META_TILE_MAXIMIZED; else window->tile_mode = META_TILE_NONE; + + if (window->tile_mode != META_TILE_NONE) + window->tile_monitor_number = monitor->number; } /* shake loose (unmaximize) maximized or tiled window if dragged beyond @@ -9271,17 +9285,18 @@ void meta_window_get_current_tile_area (MetaWindow *window, MetaRectangle *tile_area) { - const MetaMonitorInfo *monitor; + int tile_monitor_number; g_return_if_fail (window->tile_mode != META_TILE_NONE); - /* The definition of "current" of meta_window_get_work_area_current_monitor() - * and meta_screen_get_current_monitor() is slightly different: the former - * refers to the monitor which contains the largest part of the window, the - * latter to the one where the pointer is located. - */ - monitor = meta_screen_get_current_monitor (window->screen); - meta_window_get_work_area_for_monitor (window, monitor->number, tile_area); + tile_monitor_number = window->tile_monitor_number; + if (tile_monitor_number < 0) + { + meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC); + tile_monitor_number = 0; + } + + meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area); if (window->tile_mode == META_TILE_LEFT || window->tile_mode == META_TILE_RIGHT)