screen: make "monitor under pointer" logic work for several devices

This commit is contained in:
Carlos Garnacho 2011-07-03 21:29:12 +02:00
parent 0b8848057b
commit 7d5e7ec3e6
4 changed files with 38 additions and 32 deletions

View File

@ -90,6 +90,7 @@ northwestcmp (gconstpointer a, gconstpointer b)
static void static void
find_next_cascade (MetaWindow *window, find_next_cascade (MetaWindow *window,
MetaDevice *pointer,
MetaFrameBorders *borders, MetaFrameBorders *borders,
/* visible windows on relevant workspaces */ /* visible windows on relevant workspaces */
GList *windows, GList *windows,
@ -136,7 +137,7 @@ find_next_cascade (MetaWindow *window,
* of NW corner of window frame. * 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); meta_window_get_work_area_for_monitor (window, current->number, &work_area);
cascade_x = MAX (0, work_area.x); cascade_x = MAX (0, work_area.x);
@ -667,6 +668,7 @@ meta_window_place (MetaWindow *window,
{ {
GList *windows; GList *windows;
const MetaMonitorInfo *xi; const MetaMonitorInfo *xi;
MetaDevice *pointer, *keyboard;
/* frame member variables should NEVER be used in here, only /* frame member variables should NEVER be used in here, only
* MetaFrameBorders. But remember borders == NULL * MetaFrameBorders. But remember borders == NULL
@ -678,6 +680,8 @@ meta_window_place (MetaWindow *window,
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
windows = NULL; windows = NULL;
pointer = meta_window_guess_grab_pointer (window);
keyboard = meta_device_get_paired_device (pointer);
switch (window->type) switch (window->type)
{ {
@ -822,7 +826,7 @@ meta_window_place (MetaWindow *window,
int w, h; int w, h;
/* Warning, this function is a round trip! */ /* 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; w = xi->rect.width;
h = xi->rect.height; h = xi->rect.height;
@ -867,7 +871,7 @@ meta_window_place (MetaWindow *window,
} }
/* Warning, this is a round trip! */ /* 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 */ /* "Origin" placement algorithm */
x = xi->rect.x; x = xi->rect.x;
@ -907,7 +911,7 @@ meta_window_place (MetaWindow *window,
* fully overlapping window (e.g. starting multiple terminals) * fully overlapping window (e.g. starting multiple terminals)
* */ * */
if (x == xi->rect.x && y == xi->rect.y) if (x == xi->rect.x && y == xi->rect.y)
find_next_cascade (window, borders, windows, x, y, &x, &y); find_next_cascade (window, pointer, borders, windows, x, y, &x, &y);
done_check_denied_focus: done_check_denied_focus:
/* If the window is being denied focus and isn't a transient of the /* 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; gboolean found_fit;
MetaWindow *focus_window; MetaWindow *focus_window;
MetaRectangle overlap; MetaRectangle overlap;
MetaDevice *pointer, *keyboard;
MetaFocusInfo *focus_info; 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); focus_info = meta_display_get_focus_info (window->display, keyboard);
g_assert (focus_info != NULL); g_assert (focus_info != NULL);

View File

@ -186,7 +186,8 @@ void meta_screen_tile_preview_hide (MetaScreen *screen);
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one); 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, const MetaMonitorInfo* meta_screen_get_monitor_for_rect (MetaScreen *screen,
MetaRectangle *rect); MetaRectangle *rect);
const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen *screen, const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen *screen,

View File

@ -42,6 +42,7 @@
#include <meta/compositor.h> #include <meta/compositor.h>
#include "mutter-marshal.h" #include "mutter-marshal.h"
#include "mutter-enum-types.h" #include "mutter-enum-types.h"
#include "device-pointer.h"
#ifdef HAVE_SOLARIS_XINERAMA #ifdef HAVE_SOLARIS_XINERAMA
#include <X11/extensions/xinerama.h> #include <X11/extensions/xinerama.h>
@ -1941,13 +1942,17 @@ meta_screen_tile_preview_update_timeout (gpointer data)
gboolean composited = screen->display->compositor != NULL; gboolean composited = screen->display->compositor != NULL;
gboolean needs_preview = FALSE; gboolean needs_preview = FALSE;
MetaGrabInfo *grab_info; MetaGrabInfo *grab_info;
MetaDevice *pointer = NULL;
GHashTableIter iter; GHashTableIter iter;
/* FIXME: we're just handling the first grab we find */ /* FIXME: we're just handling the first grab we find */
g_hash_table_iter_init (&iter, screen->display->current_grabs); g_hash_table_iter_init (&iter, screen->display->current_grabs);
if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info)) 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; screen->tile_preview_timeout_id = 0;
@ -2153,6 +2158,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
const MetaMonitorInfo* current; const MetaMonitorInfo* current;
const MetaMonitorInfo* tmp; const MetaMonitorInfo* tmp;
GQueue* monitor_queue; GQueue* monitor_queue;
MetaDevice *pointer;
int* visited; int* visited;
int cur = 0; int cur = 0;
int i; int i;
@ -2160,6 +2166,9 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
*n_monitors = screen->n_monitor_infos; *n_monitors = screen->n_monitor_infos;
*monitors_list = g_new (int, 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 /* we calculate a natural ordering by which to choose monitors for
* window placement. We start at the current monitor, and perform * window placement. We start at the current monitor, and perform
* a breadth-first search of the monitors starting from that * 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; visited[i] = FALSE;
} }
current = meta_screen_get_current_monitor (screen); current = meta_screen_get_current_monitor (screen, pointer);
monitor_queue = g_queue_new (); monitor_queue = g_queue_new ();
g_queue_push_tail (monitor_queue, (gpointer) current); g_queue_push_tail (monitor_queue, (gpointer) current);
visited[current->number] = TRUE; visited[current->number] = TRUE;
@ -2241,7 +2250,8 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
} }
const MetaMonitorInfo* const MetaMonitorInfo*
meta_screen_get_current_monitor (MetaScreen *screen) meta_screen_get_current_monitor (MetaScreen *screen,
MetaDevice *pointer)
{ {
if (screen->n_monitor_infos == 1) if (screen->n_monitor_infos == 1)
return &screen->monitor_infos[0]; return &screen->monitor_infos[0];
@ -2251,24 +2261,18 @@ meta_screen_get_current_monitor (MetaScreen *screen)
if (screen->display->monitor_cache_invalidated) if (screen->display->monitor_cache_invalidated)
{ {
Window root_return, child_return;
int win_x_return, win_y_return;
unsigned int mask_return;
int i; int i;
MetaRectangle pointer_position; MetaRectangle pointer_position;
screen->display->monitor_cache_invalidated = FALSE; screen->display->monitor_cache_invalidated = FALSE;
pointer_position.width = pointer_position.height = 1; pointer_position.width = pointer_position.height = 1;
XQueryPointer (screen->display->xdisplay, meta_device_pointer_query_position (META_DEVICE_POINTER (pointer),
screen->xroot, screen->xroot,
&root_return, NULL, NULL,
&child_return, &pointer_position.x,
&pointer_position.x, &pointer_position.y,
&pointer_position.y, NULL, NULL, NULL);
&win_x_return,
&win_y_return,
&mask_return);
screen->last_monitor_index = 0; screen->last_monitor_index = 0;
for (i = 0; i < screen->n_monitor_infos; i++) for (i = 0; i < screen->n_monitor_infos; i++)

View File

@ -3624,7 +3624,8 @@ meta_window_can_tile_maximized (MetaWindow *window)
} }
static gboolean 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; const MetaMonitorInfo *monitor;
MetaRectangle tile_area; MetaRectangle tile_area;
@ -3632,7 +3633,7 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
if (!meta_window_can_tile_maximized (window)) if (!meta_window_can_tile_maximized (window))
return FALSE; 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); meta_window_get_work_area_for_monitor (window, monitor->number, &tile_area);
/* Do not allow tiling in portrait orientation */ /* 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, * refers to the monitor which contains the largest part of the window,
* the latter to the one where the pointer is located. * 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, meta_window_get_work_area_for_monitor (window,
monitor->number, monitor->number,
&work_area); &work_area);
@ -8619,10 +8620,10 @@ update_move (MetaWindow *window,
/* Check if the cursor is in a position which triggers tiling /* Check if the cursor is in a position which triggers tiling
* and set tile_mode accordingly. * 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)) x >= monitor->rect.x && x < (work_area.x + shake_threshold))
window->tile_mode = META_TILE_LEFT; 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 >= work_area.x + work_area.width - shake_threshold &&
x < (monitor->rect.x + monitor->rect.width)) x < (monitor->rect.x + monitor->rect.width))
window->tile_mode = META_TILE_RIGHT; window->tile_mode = META_TILE_RIGHT;