From dfcd079ec22a405b38948a9ff7bf575bb474d272 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/constraints.c | 5 ++++- src/core/place.c | 22 +++++++++++----------- src/core/screen-private.h | 3 ++- src/core/screen.c | 36 ++++++++++++++++++++---------------- src/core/window-private.h | 1 + src/core/window.c | 14 ++++++++------ 6 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index b6014613d..461a80910 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -885,6 +885,7 @@ constrain_tiling (MetaWindow *window, gboolean hminbad, vminbad; gboolean horiz_equal, vert_equal; gboolean constraint_already_satisfied; + MetaDevice *pointer; if (priority > PRIORITY_TILING) return TRUE; @@ -893,10 +894,12 @@ constrain_tiling (MetaWindow *window, if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) return TRUE; + pointer = meta_window_guess_grab_pointer (window); + /* Calculate target_size - as the tile previews need this as well, we * use an external function for the actual calculation */ - meta_window_get_current_tile_area (window, &target_size); + meta_window_get_current_tile_area (window, pointer, &target_size); unextend_by_frame (&target_size, info->fgeom); /* Check min size constraints; max size constraints are ignored as for diff --git a/src/core/place.c b/src/core/place.c index 9c657897a..9e032a8c5 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, MetaFrameGeometry *fgeom, /* 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 * MetaFrameGeometry. But remember fgeom == 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, fgeom, windows, x, y, &x, &y); + if (x == xi->rect.x && y == xi->rect.y) + find_next_cascade (window, pointer, fgeom, 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 acb826a85..afabf5b48 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -184,7 +184,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 c46b101a3..035bf867f 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 @@ -1863,13 +1864,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; @@ -1912,7 +1917,7 @@ meta_screen_tile_preview_update_timeout (gpointer data) { MetaRectangle tile_rect; - meta_window_get_current_tile_area (window, &tile_rect); + meta_window_get_current_tile_area (window, pointer, &tile_rect); meta_tile_preview_show (screen->tile_preview, pointer, &tile_rect); } else @@ -2075,6 +2080,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; @@ -2082,6 +2088,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 @@ -2096,7 +2105,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; @@ -2163,7 +2172,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]; @@ -2173,24 +2183,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-private.h b/src/core/window-private.h index 20a9e1e68..a17ffbd1b 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -604,6 +604,7 @@ void meta_window_get_work_area_all_monitors (MetaWindow *window, MetaRectangle *area); void meta_window_get_current_tile_area (MetaWindow *window, + MetaDevice *device, MetaRectangle *tile_area); diff --git a/src/core/window.c b/src/core/window.c index ab016b521..723dc941e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3536,7 +3536,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; @@ -3544,7 +3545,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 */ @@ -8424,7 +8425,7 @@ update_move (MetaWindow *window, * inside edge, because we don't want to force users to maximize * windows they are placing near the top of their screens. */ - 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); @@ -8432,10 +8433,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; @@ -9353,6 +9354,7 @@ meta_window_get_work_area_all_monitors (MetaWindow *window, void meta_window_get_current_tile_area (MetaWindow *window, + MetaDevice *pointer, MetaRectangle *tile_area) { const MetaMonitorInfo *monitor; @@ -9364,7 +9366,7 @@ meta_window_get_current_tile_area (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, pointer); meta_window_get_work_area_for_monitor (window, monitor->number, tile_area); if (window->tile_mode == META_TILE_LEFT ||