From 7d5e7ec3e6fe446d9017488f1753d53e4982e2e1 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 3 Jul 2011 21:29:12 +0200 Subject: [PATCH] screen: make "monitor under pointer" logic work for several devices --- src/core/place.c | 22 +++++++++++----------- src/core/screen-private.h | 3 ++- src/core/screen.c | 34 +++++++++++++++++++--------------- src/core/window.c | 11 ++++++----- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/core/place.c b/src/core/place.c index 51c188aa4..7abf7ff1a 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -90,6 +90,7 @@ northwestcmp (gconstpointer a, gconstpointer b) static void find_next_cascade (MetaWindow *window, + MetaDevice *pointer, MetaFrameBorders *borders, /* visible windows on relevant workspaces */ GList *windows, @@ -136,7 +137,7 @@ find_next_cascade (MetaWindow *window, * of NW corner of window frame. */ - current = meta_screen_get_current_monitor (window->screen); + current = meta_screen_get_current_monitor (window->screen, pointer); meta_window_get_work_area_for_monitor (window, current->number, &work_area); cascade_x = MAX (0, work_area.x); @@ -667,6 +668,7 @@ meta_window_place (MetaWindow *window, { GList *windows; const MetaMonitorInfo *xi; + MetaDevice *pointer, *keyboard; /* frame member variables should NEVER be used in here, only * MetaFrameBorders. But remember borders == NULL @@ -678,7 +680,9 @@ meta_window_place (MetaWindow *window, meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); windows = NULL; - + pointer = meta_window_guess_grab_pointer (window); + keyboard = meta_device_get_paired_device (pointer); + switch (window->type) { /* Run placement algorithm on these. */ @@ -822,7 +826,7 @@ meta_window_place (MetaWindow *window, int w, h; /* Warning, this function is a round trip! */ - xi = meta_screen_get_current_monitor (window->screen); + xi = meta_screen_get_current_monitor (window->screen, pointer); w = xi->rect.width; h = xi->rect.height; @@ -867,8 +871,8 @@ meta_window_place (MetaWindow *window, } /* Warning, this is a round trip! */ - xi = meta_screen_get_current_monitor (window->screen); - + xi = meta_screen_get_current_monitor (window->screen, pointer); + /* "Origin" placement algorithm */ x = xi->rect.x; y = xi->rect.y; @@ -906,8 +910,8 @@ meta_window_place (MetaWindow *window, /* If no placement has been done, revert to cascade to avoid * fully overlapping window (e.g. starting multiple terminals) * */ - if (x == xi->rect.x && y == xi->rect.y) - find_next_cascade (window, borders, windows, x, y, &x, &y); + if (x == xi->rect.x && y == xi->rect.y) + find_next_cascade (window, pointer, borders, windows, x, y, &x, &y); done_check_denied_focus: /* If the window is being denied focus and isn't a transient of the @@ -920,12 +924,8 @@ meta_window_place (MetaWindow *window, gboolean found_fit; MetaWindow *focus_window; MetaRectangle overlap; - MetaDevice *pointer, *keyboard; MetaFocusInfo *focus_info; - pointer = meta_window_guess_grab_pointer (window); - keyboard = meta_device_get_paired_device (pointer); - focus_info = meta_display_get_focus_info (window->display, keyboard); g_assert (focus_info != NULL); diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 866f5fb05..c18efa597 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -186,7 +186,8 @@ void meta_screen_tile_preview_hide (MetaScreen *screen); MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, MetaWindow *not_this_one); -const MetaMonitorInfo* meta_screen_get_current_monitor (MetaScreen *screen); +const MetaMonitorInfo* meta_screen_get_current_monitor (MetaScreen *screen, + MetaDevice *pointer); const MetaMonitorInfo* meta_screen_get_monitor_for_rect (MetaScreen *screen, MetaRectangle *rect); const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen *screen, diff --git a/src/core/screen.c b/src/core/screen.c index 41ecab1d7..61987155b 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -42,6 +42,7 @@ #include #include "mutter-marshal.h" #include "mutter-enum-types.h" +#include "device-pointer.h" #ifdef HAVE_SOLARIS_XINERAMA #include @@ -1941,13 +1942,17 @@ meta_screen_tile_preview_update_timeout (gpointer data) gboolean composited = screen->display->compositor != NULL; gboolean needs_preview = FALSE; MetaGrabInfo *grab_info; + MetaDevice *pointer = NULL; GHashTableIter iter; /* FIXME: we're just handling the first grab we find */ g_hash_table_iter_init (&iter, screen->display->current_grabs); if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info)) - window = grab_info->grab_window; + { + window = grab_info->grab_window; + pointer = grab_info->grab_pointer; + } screen->tile_preview_timeout_id = 0; @@ -2153,6 +2158,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, const MetaMonitorInfo* current; const MetaMonitorInfo* tmp; GQueue* monitor_queue; + MetaDevice *pointer; int* visited; int cur = 0; int i; @@ -2160,6 +2166,9 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, *n_monitors = screen->n_monitor_infos; *monitors_list = g_new (int, screen->n_monitor_infos); + pointer = meta_device_map_lookup (screen->display->device_map, + META_CORE_POINTER_ID); + /* we calculate a natural ordering by which to choose monitors for * window placement. We start at the current monitor, and perform * a breadth-first search of the monitors starting from that @@ -2174,7 +2183,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, visited[i] = FALSE; } - current = meta_screen_get_current_monitor (screen); + current = meta_screen_get_current_monitor (screen, pointer); monitor_queue = g_queue_new (); g_queue_push_tail (monitor_queue, (gpointer) current); visited[current->number] = TRUE; @@ -2241,7 +2250,8 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, } const MetaMonitorInfo* -meta_screen_get_current_monitor (MetaScreen *screen) +meta_screen_get_current_monitor (MetaScreen *screen, + MetaDevice *pointer) { if (screen->n_monitor_infos == 1) return &screen->monitor_infos[0]; @@ -2251,24 +2261,18 @@ meta_screen_get_current_monitor (MetaScreen *screen) if (screen->display->monitor_cache_invalidated) { - Window root_return, child_return; - int win_x_return, win_y_return; - unsigned int mask_return; int i; MetaRectangle pointer_position; screen->display->monitor_cache_invalidated = FALSE; pointer_position.width = pointer_position.height = 1; - XQueryPointer (screen->display->xdisplay, - screen->xroot, - &root_return, - &child_return, - &pointer_position.x, - &pointer_position.y, - &win_x_return, - &win_y_return, - &mask_return); + meta_device_pointer_query_position (META_DEVICE_POINTER (pointer), + screen->xroot, + NULL, NULL, + &pointer_position.x, + &pointer_position.y, + NULL, NULL, NULL); screen->last_monitor_index = 0; for (i = 0; i < screen->n_monitor_infos; i++) diff --git a/src/core/window.c b/src/core/window.c index 684ca8bda..030395824 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3624,7 +3624,8 @@ meta_window_can_tile_maximized (MetaWindow *window) } static gboolean -meta_window_can_tile_side_by_side (MetaWindow *window) +meta_window_can_tile_side_by_side (MetaWindow *window, + MetaDevice *pointer) { const MetaMonitorInfo *monitor; MetaRectangle tile_area; @@ -3632,7 +3633,7 @@ meta_window_can_tile_side_by_side (MetaWindow *window) if (!meta_window_can_tile_maximized (window)) return FALSE; - monitor = meta_screen_get_current_monitor (window->screen); + monitor = meta_screen_get_current_monitor (window->screen, pointer); meta_window_get_work_area_for_monitor (window, monitor->number, &tile_area); /* Do not allow tiling in portrait orientation */ @@ -8611,7 +8612,7 @@ update_move (MetaWindow *window, * 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); + monitor = meta_screen_get_current_monitor (window->screen, device); meta_window_get_work_area_for_monitor (window, monitor->number, &work_area); @@ -8619,10 +8620,10 @@ update_move (MetaWindow *window, /* Check if the cursor is in a position which triggers tiling * and set tile_mode accordingly. */ - if (meta_window_can_tile_side_by_side (window) && + if (meta_window_can_tile_side_by_side (window, device) && x >= monitor->rect.x && x < (work_area.x + shake_threshold)) window->tile_mode = META_TILE_LEFT; - else if (meta_window_can_tile_side_by_side (window) && + else if (meta_window_can_tile_side_by_side (window, device) && x >= work_area.x + work_area.width - shake_threshold && x < (monitor->rect.x + monitor->rect.width)) window->tile_mode = META_TILE_RIGHT;