core: Keep track of per pointer/keyboard grabs

There is now a MetaGrabInfo struct, holding all information about
an ongoing grab, there were unfortunately no means of making this
commit smaller, as things are too intertwined to separate it,

On places where it was most obvious, the correct device has been
used (in reaction to events, for example), in other parts, the
private API has been extended to include the MetaDevice (or device
ID for core.h functions), in other places, the virtual core
pointer/keyboard are used out of cluelessness.
This commit is contained in:
Carlos Garnacho 2011-06-19 00:55:10 +02:00
parent d664579115
commit c352e1078e
23 changed files with 1122 additions and 664 deletions

View File

@ -364,8 +364,17 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
gboolean pointer_grabbed = FALSE; gboolean pointer_grabbed = FALSE;
gboolean keyboard_grabbed = FALSE; gboolean keyboard_grabbed = FALSE;
int result; int result;
MetaDevice *device;
MetaGrabInfo *grab_info;
if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE) /* FIXME: need a real device here, and probably
* some exclusion mode for other devices */
device = meta_device_map_lookup (display->device_map,
META_CORE_POINTER_ID);
grab_info = meta_display_get_grab_info (display, device);
if (compositor->modal_plugin != NULL || grab_info != NULL)
return FALSE; return FALSE;
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0) if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
@ -397,11 +406,13 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
keyboard_grabbed = TRUE; keyboard_grabbed = TRUE;
} }
display->grab_op = META_GRAB_OP_COMPOSITOR; grab_info = meta_display_create_grab_info (display, device);
display->grab_window = NULL;
display->grab_screen = screen; grab_info->grab_op = META_GRAB_OP_COMPOSITOR;
display->grab_have_pointer = TRUE; grab_info->grab_window = NULL;
display->grab_have_keyboard = TRUE; grab_info->grab_screen = screen;
grab_info->grab_have_pointer = TRUE;
grab_info->grab_have_keyboard = TRUE;
compositor->modal_plugin = plugin; compositor->modal_plugin = plugin;
@ -424,18 +435,18 @@ meta_end_modal_for_plugin (MetaScreen *screen,
MetaDisplay *display = meta_screen_get_display (screen); MetaDisplay *display = meta_screen_get_display (screen);
Display *xdpy = meta_display_get_xdisplay (display); Display *xdpy = meta_display_get_xdisplay (display);
MetaCompositor *compositor = display->compositor; MetaCompositor *compositor = display->compositor;
MetaDevice *device;
g_return_if_fail (compositor->modal_plugin == plugin); g_return_if_fail (compositor->modal_plugin == plugin);
/* FIXME: need a real device here */
device = meta_device_map_lookup (display->device_map,
META_CORE_POINTER_ID);
XUngrabPointer (xdpy, timestamp); XUngrabPointer (xdpy, timestamp);
XUngrabKeyboard (xdpy, timestamp); XUngrabKeyboard (xdpy, timestamp);
display->grab_op = META_GRAB_OP_NONE; meta_display_remove_grab_info (display, device);
display->grab_window = NULL;
display->grab_screen = NULL;
display->grab_have_pointer = FALSE;
display->grab_have_keyboard = FALSE;
compositor->modal_plugin = NULL; compositor->modal_plugin = NULL;
} }

View File

@ -1362,15 +1362,18 @@ constrain_titlebar_visible (MetaWindow *window,
int bottom_amount; int bottom_amount;
int horiz_amount_offscreen, vert_amount_offscreen; int horiz_amount_offscreen, vert_amount_offscreen;
int horiz_amount_onscreen, vert_amount_onscreen; int horiz_amount_onscreen, vert_amount_onscreen;
MetaGrabInfo *grab_info;
if (priority > PRIORITY_TITLEBAR_VISIBLE) if (priority > PRIORITY_TITLEBAR_VISIBLE)
return TRUE; return TRUE;
grab_info = window->cur_grab;
/* Allow the titlebar beyond the top of the screen only if the user wasn't /* Allow the titlebar beyond the top of the screen only if the user wasn't
* clicking on the frame to start the move. * clicking on the frame to start the move.
*/ */
unconstrained_user_action = unconstrained_user_action =
info->is_user_action && !window->display->grab_frame_action; info->is_user_action && (!grab_info || !grab_info->grab_frame_action);
/* Exit early if we know the constraint won't apply--note that this constraint /* Exit early if we know the constraint won't apply--note that this constraint
* is only meant for normal windows (e.g. we don't want docks to be shoved * is only meant for normal windows (e.g. we don't want docks to be shoved

View File

@ -268,16 +268,21 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
void void
meta_core_lower_beneath_grab_window (Display *xdisplay, meta_core_lower_beneath_grab_window (Display *xdisplay,
Window xwindow, Window xwindow,
int device_id,
guint32 timestamp) guint32 timestamp)
{ {
XWindowChanges changes; XWindowChanges changes;
MetaDisplay *display; MetaDisplay *display;
MetaScreen *screen; MetaScreen *screen;
MetaWindow *grab_window; MetaWindow *grab_window;
MetaDevice *pointer;
MetaGrabInfo *grab_info;
display = meta_display_for_x_display (xdisplay); display = meta_display_for_x_display (xdisplay);
screen = meta_display_screen_for_xwindow (display, xwindow); screen = meta_display_screen_for_xwindow (display, xwindow);
grab_window = display->grab_window; pointer = meta_device_map_lookup (display->device_map, device_id);
grab_info = meta_display_get_grab_info (display, pointer);
grab_window = grab_info->grab_window;
if (grab_window == NULL) if (grab_window == NULL)
return; return;
@ -643,6 +648,7 @@ meta_core_get_workspace_name_with_index (Display *xdisplay,
gboolean gboolean
meta_core_begin_grab_op (Display *xdisplay, meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow, Window frame_xwindow,
int device_id,
MetaGrabOp op, MetaGrabOp op,
gboolean pointer_already_grabbed, gboolean pointer_already_grabbed,
gboolean frame_action, gboolean frame_action,
@ -655,13 +661,16 @@ meta_core_begin_grab_op (Display *xdisplay,
MetaWindow *window = get_window (xdisplay, frame_xwindow); MetaWindow *window = get_window (xdisplay, frame_xwindow);
MetaDisplay *display; MetaDisplay *display;
MetaScreen *screen; MetaScreen *screen;
MetaDevice *device;
display = meta_display_for_x_display (xdisplay); display = meta_display_for_x_display (xdisplay);
screen = meta_display_screen_for_xwindow (display, frame_xwindow); screen = meta_display_screen_for_xwindow (display, frame_xwindow);
g_assert (screen != NULL); g_assert (screen != NULL);
return meta_display_begin_grab_op (display, screen, window, device = meta_device_map_lookup (display->device_map, device_id);
return meta_display_begin_grab_op (display, screen, window, device,
op, pointer_already_grabbed, op, pointer_already_grabbed,
frame_action, frame_action,
button, modmask, button, modmask,
@ -670,59 +679,60 @@ meta_core_begin_grab_op (Display *xdisplay,
void void
meta_core_end_grab_op (Display *xdisplay, meta_core_end_grab_op (Display *xdisplay,
int device_id,
guint32 timestamp) guint32 timestamp)
{ {
MetaDisplay *display; MetaDisplay *display;
MetaDevice *device;
display = meta_display_for_x_display (xdisplay); display = meta_display_for_x_display (xdisplay);
device = meta_device_map_lookup (display->device_map, device_id);
meta_display_end_grab_op (display, timestamp); meta_display_end_grab_op (display, device, timestamp);
} }
MetaGrabOp MetaGrabOp
meta_core_get_grab_op (Display *xdisplay) meta_core_frame_has_grab (Display *xdisplay,
Window frame_xwindow,
gint *device_id,
gint *button_ret)
{ {
MetaDisplay *display; MetaWindow *window;
display = meta_display_for_x_display (xdisplay); window = get_window (xdisplay, frame_xwindow);
return display->grab_op; if (window != NULL &&
window->cur_grab != NULL)
{
if (button_ret)
*button_ret = window->cur_grab->grab_button;
if (device_id)
*device_id = meta_device_get_id (window->cur_grab->grab_pointer);
return window->cur_grab->grab_op;
}
return META_GRAB_OP_NONE;
} }
Window Window
meta_core_get_grab_frame (Display *xdisplay) meta_core_get_frame (Display *xdisplay,
Window client_xwindow)
{ {
MetaDisplay *display; MetaDisplay *display;
MetaWindow *window;
display = meta_display_for_x_display (xdisplay); display = meta_display_for_x_display (xdisplay);
window = meta_display_lookup_x_window (display, client_xwindow);
g_assert (display != NULL); if (window &&
g_assert (display->grab_op == META_GRAB_OP_NONE || window->frame)
display->grab_screen != NULL); return window->frame->xwindow;
g_assert (display->grab_op == META_GRAB_OP_NONE ||
display->grab_screen->display->xdisplay == xdisplay);
if (display->grab_op != META_GRAB_OP_NONE &&
display->grab_window &&
display->grab_window->frame)
return display->grab_window->frame->xwindow;
else
return None; return None;
} }
int
meta_core_get_grab_button (Display *xdisplay)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
if (display->grab_op == META_GRAB_OP_NONE)
return -1;
return display->grab_button;
}
void void
meta_core_grab_buttons (Display *xdisplay, meta_core_grab_buttons (Display *xdisplay,
Window frame_xwindow) Window frame_xwindow)

View File

@ -118,6 +118,7 @@ void meta_core_user_focus (Display *xdisplay,
void meta_core_lower_beneath_grab_window (Display *xdisplay, void meta_core_lower_beneath_grab_window (Display *xdisplay,
Window xwindow, Window xwindow,
int device_id,
guint32 timestamp); guint32 timestamp);
void meta_core_minimize (Display *xdisplay, void meta_core_minimize (Display *xdisplay,
@ -175,6 +176,7 @@ void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
gboolean meta_core_begin_grab_op (Display *xdisplay, gboolean meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow, Window frame_xwindow,
int device_id,
MetaGrabOp op, MetaGrabOp op,
gboolean pointer_already_grabbed, gboolean pointer_already_grabbed,
gboolean frame_action, gboolean frame_action,
@ -184,11 +186,15 @@ gboolean meta_core_begin_grab_op (Display *xdisplay,
int root_x, int root_x,
int root_y); int root_y);
void meta_core_end_grab_op (Display *xdisplay, void meta_core_end_grab_op (Display *xdisplay,
int device_id,
guint32 timestamp); guint32 timestamp);
MetaGrabOp meta_core_get_grab_op (Display *xdisplay);
Window meta_core_get_grab_frame (Display *xdisplay);
int meta_core_get_grab_button (Display *xdisplay);
MetaGrabOp meta_core_frame_has_grab (Display *xdisplay,
Window frame_xwindow,
gint *device_id,
gint *button_ret);
Window meta_core_get_frame (Display *xdisplay,
Window client_xwindow);
void meta_core_grab_buttons (Display *xdisplay, void meta_core_grab_buttons (Display *xdisplay,
Window frame_xwindow); Window frame_xwindow);

View File

@ -35,6 +35,12 @@
#include "display-private.h" #include "display-private.h"
#include "device-private.h" #include "device-private.h"
/* Device IDs for Virtual Core Pointer/Keyboard,
* use only in case of emergency.
*/
#define META_CORE_POINTER_ID 2
#define META_CORE_KEYBOARD_ID 3
struct _MetaDeviceMap struct _MetaDeviceMap
{ {
GObject parent_instance; GObject parent_instance;

View File

@ -24,6 +24,7 @@
#include <config.h> #include <config.h>
#include "screen-private.h" #include "screen-private.h"
#include "devices-core.h" #include "devices-core.h"
#include "device-map-private.h"
/* Common functions */ /* Common functions */
static void static void

View File

@ -32,11 +32,6 @@
#include "device-pointer.h" #include "device-pointer.h"
#include "device-keyboard.h" #include "device-keyboard.h"
/* These IDs are the same than those of the
* VCP/VCK in XInput2, to keep consistency */
#define META_CORE_POINTER_ID 2
#define META_CORE_KEYBOARD_ID 3
/* Pointer */ /* Pointer */
#define META_TYPE_DEVICE_POINTER_CORE (meta_device_pointer_core_get_type ()) #define META_TYPE_DEVICE_POINTER_CORE (meta_device_pointer_core_get_type ())
#define META_DEVICE_POINTER_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCore)) #define META_DEVICE_POINTER_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCore))

View File

@ -57,6 +57,8 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
typedef struct _MetaGrabInfo MetaGrabInfo;
typedef void (* MetaWindowPingFunc) (MetaDisplay *display, typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
Window xwindow, Window xwindow,
guint32 timestamp, guint32 timestamp,
@ -85,6 +87,45 @@ typedef enum {
META_TILE_MAXIMIZED META_TILE_MAXIMIZED
} MetaTileMode; } MetaTileMode;
struct _MetaGrabInfo
{
MetaDevice *grab_pointer;
MetaDevice *grab_keyboard;
MetaGrabOp grab_op;
MetaScreen *grab_screen;
MetaWindow *grab_window;
Window grab_xwindow;
int grab_button;
int grab_anchor_root_x;
int grab_anchor_root_y;
MetaRectangle grab_anchor_window_pos;
MetaTileMode grab_tile_mode;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_frame_action : 1;
/* During a resize operation, the directions in which we've broken
* out of the initial maximization state */
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
guint32 grab_motion_notify_time;
GList* grab_old_window_stacking;
unsigned int grab_last_user_action_was_snap;
#ifdef HAVE_XSYNC
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
XSyncAlarm grab_sync_request_alarm;
#endif
int grab_resize_timeout_id;
};
struct _MetaDisplay struct _MetaDisplay
{ {
GObject parent_instance; GObject parent_instance;
@ -178,34 +219,11 @@ struct _MetaDisplay
/* Alt+click button grabs */ /* Alt+click button grabs */
unsigned int window_grab_modifiers; unsigned int window_grab_modifiers;
/* current window operation */ /* per-device current window operation */
MetaGrabOp grab_op; GHashTable *current_grabs;
MetaScreen *grab_screen;
MetaWindow *grab_window; /* per-screen edge resistance cache */
Window grab_xwindow; GHashTable *edge_resistance_info;
int grab_button;
int grab_anchor_root_x;
int grab_anchor_root_y;
MetaRectangle grab_anchor_window_pos;
MetaTileMode grab_tile_mode;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_frame_action : 1;
/* During a resize operation, the directions in which we've broken
* out of the initial maximization state */
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
guint32 grab_motion_notify_time;
GList* grab_old_window_stacking;
MetaEdgeResistanceData *grab_edge_resistance_data;
unsigned int grab_last_user_action_was_snap;
/* we use property updates as sentinels for certain window focus events /* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events * to avoid some race conditions on EnterNotify events
@ -216,11 +234,6 @@ struct _MetaDisplay
int xkb_base_event_type; int xkb_base_event_type;
guint32 last_bell_time; guint32 last_bell_time;
#endif #endif
#ifdef HAVE_XSYNC
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
XSyncAlarm grab_sync_request_alarm;
#endif
int grab_resize_timeout_id;
/* Keybindings stuff */ /* Keybindings stuff */
MetaKeyBinding *key_bindings; MetaKeyBinding *key_bindings;
@ -388,12 +401,14 @@ Cursor meta_display_create_x_cursor (MetaDisplay *display,
void meta_display_set_grab_op_cursor (MetaDisplay *display, void meta_display_set_grab_op_cursor (MetaDisplay *display,
MetaScreen *screen, MetaScreen *screen,
MetaDevice *device,
MetaGrabOp op, MetaGrabOp op,
gboolean change_pointer, gboolean change_pointer,
Window grab_xwindow, Window grab_xwindow,
guint32 timestamp); guint32 timestamp);
void meta_display_check_threshold_reached (MetaDisplay *display, void meta_display_check_threshold_reached (MetaDisplay *display,
MetaDevice *device,
int x, int x,
int y); int y);
void meta_display_grab_window_buttons (MetaDisplay *display, void meta_display_grab_window_buttons (MetaDisplay *display,
@ -407,7 +422,8 @@ void meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window); MetaWindow *window);
/* Next function is defined in edge-resistance.c */ /* Next function is defined in edge-resistance.c */
void meta_display_cleanup_edges (MetaDisplay *display); void meta_display_cleanup_edges (MetaDisplay *display,
MetaScreen *screen);
/* make a request to ensure the event serial has changed */ /* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display); void meta_display_increment_event_serial (MetaDisplay *display);
@ -455,4 +471,12 @@ void meta_display_overlay_key_activate (MetaDisplay *display);
/* In above-tab-keycode.c */ /* In above-tab-keycode.c */
guint meta_display_get_above_tab_keycode (MetaDisplay *display); guint meta_display_get_above_tab_keycode (MetaDisplay *display);
MetaGrabInfo * meta_display_create_grab_info (MetaDisplay *display,
MetaDevice *device);
void meta_display_remove_grab_info (MetaDisplay *display,
MetaDevice *device);
MetaGrabInfo * meta_display_get_grab_info (MetaDisplay *display,
MetaDevice *device);
#endif #endif

View File

@ -48,6 +48,7 @@
#include "xprops.h" #include "xprops.h"
#include "workspace-private.h" #include "workspace-private.h"
#include "bell.h" #include "bell.h"
#include "device-keyboard.h"
#include "device-private.h" #include "device-private.h"
#include "input-events.h" #include "input-events.h"
#include <meta/compositor.h> #include <meta/compositor.h>
@ -469,16 +470,11 @@ meta_display_open (void)
the_display->autoraise_window = NULL; the_display->autoraise_window = NULL;
the_display->focus_window = NULL; the_display->focus_window = NULL;
the_display->expected_focus_window = NULL; the_display->expected_focus_window = NULL;
the_display->grab_old_window_stacking = NULL;
the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */ the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
terminal has the focus */ terminal has the focus */
#ifdef HAVE_XSYNC
the_display->grab_sync_request_alarm = None;
#endif
/* FIXME copy the checks from GDK probably */ /* FIXME copy the checks from GDK probably */
the_display->static_gravity_works = g_getenv ("MUTTER_USE_STATIC_GRAVITY") != NULL; the_display->static_gravity_works = g_getenv ("MUTTER_USE_STATIC_GRAVITY") != NULL;
@ -549,20 +545,13 @@ meta_display_open (void)
the_display->current_time = CurrentTime; the_display->current_time = CurrentTime;
the_display->sentinel_counter = 0; the_display->sentinel_counter = 0;
the_display->grab_resize_timeout_id = 0;
the_display->grab_have_keyboard = FALSE;
#ifdef HAVE_XKB #ifdef HAVE_XKB
the_display->last_bell_time = 0; the_display->last_bell_time = 0;
#endif #endif
the_display->grab_op = META_GRAB_OP_NONE; the_display->current_grabs = g_hash_table_new_full (NULL, NULL, NULL,
the_display->grab_window = NULL; (GDestroyNotify) g_free);
the_display->grab_screen = NULL; the_display->edge_resistance_info = g_hash_table_new (NULL, NULL);
the_display->grab_resize_popup = NULL;
the_display->grab_tile_mode = META_TILE_NONE;
the_display->grab_edge_resistance_data = NULL;
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
{ {
@ -994,9 +983,6 @@ meta_display_close (MetaDisplay *display,
meta_display_remove_autoraise_callback (display); meta_display_remove_autoraise_callback (display);
if (display->grab_old_window_stacking)
g_list_free (display->grab_old_window_stacking);
/* Stop caring about events */ /* Stop caring about events */
meta_ui_remove_event_func (display->xdisplay, meta_ui_remove_event_func (display->xdisplay,
event_callback, event_callback,
@ -1582,6 +1568,7 @@ event_callback (XEvent *event,
MetaWindow *window; MetaWindow *window;
MetaWindow *property_for_window; MetaWindow *property_for_window;
MetaDisplay *display; MetaDisplay *display;
MetaGrabInfo *grab_info;
Window modified; Window modified;
gboolean frame_was_receiver; gboolean frame_was_receiver;
gboolean bypass_compositor; gboolean bypass_compositor;
@ -1666,15 +1653,30 @@ event_callback (XEvent *event,
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
if (META_DISPLAY_HAS_XSYNC (display) && if (META_DISPLAY_HAS_XSYNC (display) &&
event->type == (display->xsync_event_base + XSyncAlarmNotify) && event->type == (display->xsync_event_base + XSyncAlarmNotify))
((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
{ {
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, display->current_grabs);
/* Each ongoing grab has its own sync alarm */
while (g_hash_table_iter_next (&iter, &key, &value))
{
grab_info = value;
if (((XSyncAlarmNotifyEvent*)event)->alarm != grab_info->grab_sync_request_alarm)
continue;
filter_out_event = TRUE; /* GTK doesn't want to see this really */ filter_out_event = TRUE; /* GTK doesn't want to see this really */
if (display->grab_op != META_GRAB_OP_NONE && if (grab_info->grab_op != META_GRAB_OP_NONE &&
display->grab_window != NULL && grab_info->grab_window != NULL &&
grab_op_is_mouse (display->grab_op)) grab_op_is_mouse (grab_info->grab_op))
meta_window_handle_mouse_grab_op_event (display->grab_window, event); meta_window_handle_mouse_grab_op_event (grab_info->grab_window,
event);
break;
}
} }
#endif /* HAVE_XSYNC */ #endif /* HAVE_XSYNC */
@ -1769,12 +1771,13 @@ event_callback (XEvent *event,
} }
device = meta_input_event_get_device (display, event); device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
switch (evtype) switch (evtype)
{ {
case KeyPress: case KeyPress:
case KeyRelease: case KeyRelease:
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
/* For key events, it's important to enforce single-handling, or /* For key events, it's important to enforce single-handling, or
@ -1794,26 +1797,27 @@ event_callback (XEvent *event,
&ev_root_x, &ev_root_x,
&ev_root_y); &ev_root_y);
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
if (n_button == 4 || n_button == 5) if (n_button == 4 || n_button == 5)
/* Scrollwheel event, do nothing and deliver event to compositor below */ /* Scrollwheel event, do nothing and deliver event to compositor below */
break; break;
if ((window && if (grab_info &&
grab_op_is_mouse (display->grab_op) && ((window &&
display->grab_button != (int) n_button && grab_op_is_mouse (grab_info->grab_op) &&
display->grab_window == window) || grab_info->grab_button != (int) n_button &&
grab_op_is_keyboard (display->grab_op)) grab_info->grab_window == window) ||
grab_op_is_keyboard (grab_info->grab_op)))
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Ending grab op %u on window %s due to button press\n", "Ending grab op %u on window %s due to button press\n",
display->grab_op, grab_info->grab_op,
(display->grab_window ? (grab_info->grab_window ?
display->grab_window->desc : grab_info->grab_window->desc :
"none")); "none"));
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) if (GRAB_OP_IS_WINDOW_SWITCH (grab_info->grab_op))
{ {
MetaScreen *screen; MetaScreen *screen;
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
@ -1821,13 +1825,16 @@ event_callback (XEvent *event,
screen = screen =
meta_display_screen_for_root (display, xwindow); meta_display_screen_for_root (display, xwindow);
/* FIXME: won't work well with multiple
* devices messing with stacking
*/
if (screen!=NULL) if (screen!=NULL)
meta_stack_set_positions (screen->stack, meta_stack_set_positions (screen->stack,
display->grab_old_window_stacking); grab_info->grab_old_window_stacking);
} }
meta_display_end_grab_op (display, evtime); meta_display_end_grab_op (display, device, evtime);
} }
else if (window && display->grab_op == META_GRAB_OP_NONE) else if (window && !grab_info)
{ {
gboolean begin_move = FALSE; gboolean begin_move = FALSE;
unsigned int grab_mask; unsigned int grab_mask;
@ -1920,6 +1927,7 @@ event_callback (XEvent *event,
meta_display_begin_grab_op (display, meta_display_begin_grab_op (display,
window->screen, window->screen,
window, window,
device,
op, op,
TRUE, TRUE,
FALSE, FALSE,
@ -1976,6 +1984,7 @@ event_callback (XEvent *event,
meta_display_begin_grab_op (display, meta_display_begin_grab_op (display,
window->screen, window->screen,
window, window,
device,
META_GRAB_OP_MOVING, META_GRAB_OP_MOVING,
TRUE, TRUE,
FALSE, FALSE,
@ -1988,27 +1997,30 @@ event_callback (XEvent *event,
} }
break; break;
case ButtonRelease: case ButtonRelease:
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
if (display->grab_window == window && if (grab_info &&
grab_op_is_mouse (display->grab_op)) grab_info->grab_window == window &&
grab_op_is_mouse (grab_info->grab_op))
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
break; break;
case MotionNotify: case MotionNotify:
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
if (display->grab_window == window && if (grab_info &&
grab_op_is_mouse (display->grab_op)) grab_info->grab_window == window &&
grab_op_is_mouse (grab_info->grab_op))
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
break; break;
case EnterNotify: case EnterNotify:
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
if (display->grab_window == window && if (grab_info &&
grab_op_is_mouse (display->grab_op)) grab_info->grab_window == window &&
grab_op_is_mouse (grab_info->grab_op))
{ {
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
break; break;
@ -2101,11 +2113,12 @@ event_callback (XEvent *event,
} }
break; break;
case LeaveNotify: case LeaveNotify:
if (display->grab_op == META_GRAB_OP_COMPOSITOR) if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
break; break;
if (display->grab_window == window && if (grab_info &&
grab_op_is_mouse (display->grab_op)) grab_info->grab_window == window &&
grab_op_is_mouse (grab_info->grab_op))
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
else if (window != NULL) else if (window != NULL)
{ {
@ -2226,11 +2239,15 @@ event_callback (XEvent *event,
* will change one day? * will change one day?
*/ */
guint32 timestamp; guint32 timestamp;
timestamp = meta_display_get_current_time_roundtrip (display);
if (display->grab_op != META_GRAB_OP_NONE && timestamp = meta_display_get_current_time_roundtrip (display);
display->grab_window == window) grab_info = window->cur_grab;
meta_display_end_grab_op (display, timestamp);
if (grab_info &&
grab_info->grab_op != META_GRAB_OP_NONE)
meta_display_end_grab_op (display,
grab_info->grab_pointer,
timestamp);
if (frame_was_receiver) if (frame_was_receiver)
{ {
@ -2256,12 +2273,16 @@ event_callback (XEvent *event,
* will change one day? * will change one day?
*/ */
guint32 timestamp; guint32 timestamp;
timestamp = meta_display_get_current_time_roundtrip (display);
if (display->grab_op != META_GRAB_OP_NONE && timestamp = meta_display_get_current_time_roundtrip (display);
display->grab_window == window && grab_info = window->cur_grab;
if (grab_info &&
grab_info->grab_op != META_GRAB_OP_NONE &&
((window->frame == NULL) || !window->frame->mapped)) ((window->frame == NULL) || !window->frame->mapped))
meta_display_end_grab_op (display, timestamp); meta_display_end_grab_op (display,
grab_info->grab_pointer,
timestamp);
if (!frame_was_receiver) if (!frame_was_receiver)
{ {
@ -3445,14 +3466,17 @@ xcursor_for_op (MetaDisplay *display,
void void
meta_display_set_grab_op_cursor (MetaDisplay *display, meta_display_set_grab_op_cursor (MetaDisplay *display,
MetaScreen *screen, MetaScreen *screen,
MetaDevice *device,
MetaGrabOp op, MetaGrabOp op,
gboolean change_pointer, gboolean change_pointer,
Window grab_xwindow, Window grab_xwindow,
guint32 timestamp) guint32 timestamp)
{ {
MetaGrabInfo *grab_info;
Cursor cursor; Cursor cursor;
cursor = xcursor_for_op (display, op); cursor = xcursor_for_op (display, op);
grab_info = meta_display_get_grab_info (display, device);
#define GRAB_MASK (PointerMotionMask | \ #define GRAB_MASK (PointerMotionMask | \
ButtonPressMask | ButtonReleaseMask | \ ButtonPressMask | ButtonReleaseMask | \
@ -3473,8 +3497,8 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Error trapped from XChangeActivePointerGrab()\n"); "Error trapped from XChangeActivePointerGrab()\n");
if (display->grab_have_pointer) if (grab_info->grab_have_pointer)
display->grab_have_pointer = FALSE; grab_info->grab_have_pointer = FALSE;
} }
} }
else else
@ -3491,7 +3515,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
cursor, cursor,
timestamp) == GrabSuccess) timestamp) == GrabSuccess)
{ {
display->grab_have_pointer = TRUE; grab_info->grab_have_pointer = TRUE;
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"XGrabPointer() returned GrabSuccess time %u\n", "XGrabPointer() returned GrabSuccess time %u\n",
timestamp); timestamp);
@ -3515,6 +3539,7 @@ gboolean
meta_display_begin_grab_op (MetaDisplay *display, meta_display_begin_grab_op (MetaDisplay *display,
MetaScreen *screen, MetaScreen *screen,
MetaWindow *window, MetaWindow *window,
MetaDevice *device,
MetaGrabOp op, MetaGrabOp op,
gboolean pointer_already_grabbed, gboolean pointer_already_grabbed,
gboolean frame_action, gboolean frame_action,
@ -3525,6 +3550,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
int root_y) int root_y)
{ {
MetaWindow *grab_window = NULL; MetaWindow *grab_window = NULL;
MetaGrabInfo *grab_info;
Window grab_xwindow; Window grab_xwindow;
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
@ -3532,15 +3558,21 @@ meta_display_begin_grab_op (MetaDisplay *display,
op, window ? window->desc : "none", button, pointer_already_grabbed, op, window ? window->desc : "none", button, pointer_already_grabbed,
root_x, root_y); root_x, root_y);
if (display->grab_op != META_GRAB_OP_NONE) grab_info = meta_display_get_grab_info (display, device);
if (grab_info != NULL &&
grab_info->grab_op != META_GRAB_OP_NONE)
{ {
if (window) if (window)
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n", meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
op, window->desc, display->grab_op, op, window->desc, grab_info->grab_op,
display->grab_window ? display->grab_window->desc : "none"); grab_info->grab_window ? grab_info->grab_window->desc : "none");
return FALSE; return FALSE;
} }
if (grab_info == NULL)
grab_info = meta_display_create_grab_info (display, device);
if (window && if (window &&
(meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op))) (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op)))
{ {
@ -3548,9 +3580,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
meta_window_raise (window); meta_window_raise (window);
else else
{ {
display->grab_initial_x = root_x; grab_info->grab_initial_x = root_x;
display->grab_initial_y = root_y; grab_info->grab_initial_y = root_y;
display->grab_threshold_movement_reached = FALSE; grab_info->grab_threshold_movement_reached = FALSE;
} }
} }
@ -3576,15 +3608,15 @@ meta_display_begin_grab_op (MetaDisplay *display,
else else
grab_xwindow = screen->xroot; grab_xwindow = screen->xroot;
display->grab_have_pointer = FALSE; grab_info->grab_have_pointer = FALSE;
if (pointer_already_grabbed) if (pointer_already_grabbed)
display->grab_have_pointer = TRUE; grab_info->grab_have_pointer = TRUE;
meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow, meta_display_set_grab_op_cursor (display, screen, device, op, FALSE,
timestamp); grab_xwindow, timestamp);
if (!display->grab_have_pointer) if (!grab_info->grab_have_pointer)
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"XGrabPointer() failed\n"); "XGrabPointer() failed\n");
@ -3595,63 +3627,64 @@ meta_display_begin_grab_op (MetaDisplay *display,
if (grab_op_is_keyboard (op) || grab_op_is_mouse_only (op)) if (grab_op_is_keyboard (op) || grab_op_is_mouse_only (op))
{ {
if (grab_window) if (grab_window)
display->grab_have_keyboard = grab_info->grab_have_keyboard =
meta_window_grab_all_keys (grab_window, timestamp); meta_window_grab_all_keys (grab_window, timestamp);
else else
display->grab_have_keyboard = grab_info->grab_have_keyboard =
meta_screen_grab_all_keys (screen, timestamp); meta_screen_grab_all_keys (screen, timestamp);
if (!display->grab_have_keyboard) if (!grab_info->grab_have_keyboard)
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"grabbing all keys failed, ungrabbing pointer\n"); "grabbing all keys failed, ungrabbing pointer\n");
XUngrabPointer (display->xdisplay, timestamp); XUngrabPointer (display->xdisplay, timestamp);
display->grab_have_pointer = FALSE; grab_info->grab_have_pointer = FALSE;
return FALSE; return FALSE;
} }
} }
display->grab_op = op; grab_info->grab_op = op;
display->grab_window = grab_window; grab_info->grab_window = grab_window;
display->grab_screen = screen; grab_info->grab_screen = screen;
display->grab_xwindow = grab_xwindow; grab_info->grab_xwindow = grab_xwindow;
display->grab_button = button; grab_info->grab_button = button;
display->grab_mask = modmask; grab_info->grab_mask = modmask;
if (window) if (window)
display->grab_tile_mode = window->tile_mode; grab_info->grab_tile_mode = window->tile_mode;
else else
display->grab_tile_mode = META_TILE_NONE; grab_info->grab_tile_mode = META_TILE_NONE;
display->grab_anchor_root_x = root_x; grab_info->grab_anchor_root_x = root_x;
display->grab_anchor_root_y = root_y; grab_info->grab_anchor_root_y = root_y;
display->grab_latest_motion_x = root_x; grab_info->grab_latest_motion_x = root_x;
display->grab_latest_motion_y = root_y; grab_info->grab_latest_motion_y = root_y;
display->grab_last_moveresize_time.tv_sec = 0; grab_info->grab_last_moveresize_time.tv_sec = 0;
display->grab_last_moveresize_time.tv_usec = 0; grab_info->grab_last_moveresize_time.tv_usec = 0;
display->grab_motion_notify_time = 0; grab_info->grab_motion_notify_time = 0;
display->grab_old_window_stacking = NULL; grab_info->grab_old_window_stacking = NULL;
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
display->grab_sync_request_alarm = None; grab_info->grab_sync_request_alarm = None;
display->grab_last_user_action_was_snap = FALSE; grab_info->grab_last_user_action_was_snap = FALSE;
#endif #endif
display->grab_frame_action = frame_action; grab_info->grab_frame_action = frame_action;
display->grab_resize_unmaximize = 0; grab_info->grab_resize_unmaximize = 0;
if (display->grab_resize_timeout_id) if (grab_info->grab_resize_timeout_id)
{ {
g_source_remove (display->grab_resize_timeout_id); g_source_remove (grab_info->grab_resize_timeout_id);
display->grab_resize_timeout_id = 0; grab_info->grab_resize_timeout_id = 0;
} }
if (display->grab_window) if (grab_info->grab_window)
{ {
meta_window_get_client_root_coords (display->grab_window, grab_info->grab_window->cur_grab = grab_info;
&display->grab_initial_window_pos); meta_window_get_client_root_coords (grab_info->grab_window,
display->grab_anchor_window_pos = display->grab_initial_window_pos; &grab_info->grab_initial_window_pos);
grab_info->grab_anchor_window_pos = grab_info->grab_initial_window_pos;
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
if ( meta_grab_op_is_resizing (display->grab_op) && if (meta_grab_op_is_resizing (grab_info->grab_op) &&
display->grab_window->sync_request_counter != None) grab_info->grab_window->sync_request_counter != None)
{ {
XSyncAlarmAttributes values; XSyncAlarmAttributes values;
XSyncValue init; XSyncValue init;
@ -3665,17 +3698,17 @@ meta_display_begin_grab_op (MetaDisplay *display,
XSyncIntToValue (&init, 0); XSyncIntToValue (&init, 0);
XSyncSetCounter (display->xdisplay, XSyncSetCounter (display->xdisplay,
display->grab_window->sync_request_counter, init); grab_info->grab_window->sync_request_counter, init);
display->grab_window->sync_request_serial = 0; grab_info->grab_window->sync_request_serial = 0;
display->grab_window->sync_request_time.tv_sec = 0; grab_info->grab_window->sync_request_time.tv_sec = 0;
display->grab_window->sync_request_time.tv_usec = 0; grab_info->grab_window->sync_request_time.tv_usec = 0;
values.trigger.counter = display->grab_window->sync_request_counter; values.trigger.counter = grab_info->grab_window->sync_request_counter;
values.trigger.value_type = XSyncAbsolute; values.trigger.value_type = XSyncAbsolute;
values.trigger.test_type = XSyncPositiveTransition; values.trigger.test_type = XSyncPositiveTransition;
XSyncIntToValue (&values.trigger.wait_value, XSyncIntToValue (&values.trigger.wait_value,
display->grab_window->sync_request_serial + 1); grab_info->grab_window->sync_request_serial + 1);
/* After triggering, increment test_value by this. /* After triggering, increment test_value by this.
* (NOT wait_value above) * (NOT wait_value above)
@ -3685,7 +3718,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
/* we want events (on by default anyway) */ /* we want events (on by default anyway) */
values.events = True; values.events = True;
display->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay, grab_info->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay,
XSyncCACounter | XSyncCACounter |
XSyncCAValueType | XSyncCAValueType |
XSyncCAValue | XSyncCAValue |
@ -3695,35 +3728,35 @@ meta_display_begin_grab_op (MetaDisplay *display,
&values); &values);
if (meta_error_trap_pop_with_return (display) != Success) if (meta_error_trap_pop_with_return (display) != Success)
display->grab_sync_request_alarm = None; grab_info->grab_sync_request_alarm = None;
meta_topic (META_DEBUG_RESIZING, meta_topic (META_DEBUG_RESIZING,
"Created update alarm 0x%lx\n", "Created update alarm 0x%lx\n",
display->grab_sync_request_alarm); grab_info->grab_sync_request_alarm);
} }
#endif #endif
} }
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Grab op %u on window %s successful\n", "Grab op %u on window %s successful\n",
display->grab_op, window ? window->desc : "(null)"); grab_info->grab_op, window ? window->desc : "(null)");
g_assert (display->grab_window != NULL || display->grab_screen != NULL); g_assert (grab_info->grab_window != NULL || grab_info->grab_screen != NULL);
g_assert (display->grab_op != META_GRAB_OP_NONE); g_assert (grab_info->grab_op != META_GRAB_OP_NONE);
/* Save the old stacking */ /* Save the old stacking */
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) if (GRAB_OP_IS_WINDOW_SWITCH (grab_info->grab_op))
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Saving old stack positions; old pointer was %p.\n", "Saving old stack positions; old pointer was %p.\n",
display->grab_old_window_stacking); grab_info->grab_old_window_stacking);
display->grab_old_window_stacking = grab_info->grab_old_window_stacking =
meta_stack_get_positions (screen->stack); meta_stack_get_positions (screen->stack);
} }
if (display->grab_window) if (grab_info->grab_window)
{ {
meta_window_refresh_resize_popup (display->grab_window); meta_window_refresh_resize_popup (grab_info->grab_window);
} }
return TRUE; return TRUE;
@ -3731,21 +3764,34 @@ meta_display_begin_grab_op (MetaDisplay *display,
void void
meta_display_end_grab_op (MetaDisplay *display, meta_display_end_grab_op (MetaDisplay *display,
MetaDevice *device,
guint32 timestamp) guint32 timestamp)
{ {
meta_topic (META_DEBUG_WINDOW_OPS, MetaGrabInfo *grab_info;
"Ending grab op %u at time %u\n", display->grab_op, timestamp);
if (display->grab_op == META_GRAB_OP_NONE) grab_info = meta_display_get_grab_info (display, device);
if (!grab_info)
{
meta_topic (META_DEBUG_WINDOW_OPS,
"Ending non-existent grab op at time %u\n",
timestamp);
return;
}
meta_topic (META_DEBUG_WINDOW_OPS,
"Ending grab op %u at time %u\n", grab_info->grab_op, timestamp);
if (grab_info->grab_op == META_GRAB_OP_NONE)
return; return;
if (display->grab_window != NULL) if (grab_info->grab_window != NULL)
display->grab_window->shaken_loose = FALSE; grab_info->grab_window->shaken_loose = FALSE;
if (display->grab_window != NULL && if (grab_info->grab_window != NULL &&
!meta_prefs_get_raise_on_click () && !meta_prefs_get_raise_on_click () &&
(meta_grab_op_is_moving (display->grab_op) || (meta_grab_op_is_moving (grab_info->grab_op) ||
meta_grab_op_is_resizing (display->grab_op))) meta_grab_op_is_resizing (grab_info->grab_op)))
{ {
/* Only raise the window in orthogonal raise /* Only raise the window in orthogonal raise
* ('do-not-raise-on-click') mode if the user didn't try to move * ('do-not-raise-on-click') mode if the user didn't try to move
@ -3753,85 +3799,95 @@ meta_display_end_grab_op (MetaDisplay *display,
* For raise on click mode, the window was raised at the * For raise on click mode, the window was raised at the
* beginning of the grab_op. * beginning of the grab_op.
*/ */
if (!display->grab_threshold_movement_reached) if (!grab_info->grab_threshold_movement_reached)
meta_window_raise (display->grab_window); meta_window_raise (grab_info->grab_window);
} }
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) || if (GRAB_OP_IS_WINDOW_SWITCH (grab_info->grab_op) ||
display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING) grab_info->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
{ {
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) if (GRAB_OP_IS_WINDOW_SWITCH (grab_info->grab_op))
meta_screen_tab_popup_destroy (display->grab_screen); meta_screen_tab_popup_destroy (grab_info->grab_screen);
else else
meta_screen_workspace_popup_destroy (display->grab_screen); meta_screen_workspace_popup_destroy (grab_info->grab_screen);
/* If the ungrab here causes an EnterNotify, ignore it for /* If the ungrab here causes an EnterNotify, ignore it for
* sloppy focus * sloppy focus
*/ */
display->ungrab_should_not_cause_focus_window = display->grab_xwindow; display->ungrab_should_not_cause_focus_window = grab_info->grab_xwindow;
} }
/* If this was a move or resize clear out the edge cache */ /* If this was a move or resize clear out the edge cache */
if (meta_grab_op_is_resizing (display->grab_op) || if (meta_grab_op_is_resizing (grab_info->grab_op) ||
meta_grab_op_is_moving (display->grab_op)) meta_grab_op_is_moving (grab_info->grab_op))
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Clearing out the edges for resistance/snapping"); "Clearing out the edges for resistance/snapping");
meta_display_cleanup_edges (display); meta_display_cleanup_edges (display, grab_info->grab_screen);
} }
if (display->grab_old_window_stacking != NULL) if (grab_info->grab_old_window_stacking != NULL)
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Clearing out the old stack position, which was %p.\n", "Clearing out the old stack position, which was %p.\n",
display->grab_old_window_stacking); grab_info->grab_old_window_stacking);
g_list_free (display->grab_old_window_stacking); g_list_free (grab_info->grab_old_window_stacking);
display->grab_old_window_stacking = NULL; grab_info->grab_old_window_stacking = NULL;
} }
if (display->grab_have_pointer) if (grab_info->grab_have_pointer)
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Ungrabbing pointer with timestamp %u\n", timestamp); "Ungrabbing pointer with timestamp %u\n", timestamp);
XUngrabPointer (display->xdisplay, timestamp); XUngrabPointer (display->xdisplay, timestamp);
} }
if (display->grab_have_keyboard) if (grab_info->grab_have_keyboard)
{ {
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Ungrabbing all keys timestamp %u\n", timestamp); "Ungrabbing all keys timestamp %u\n", timestamp);
if (display->grab_window) if (grab_info->grab_window)
meta_window_ungrab_all_keys (display->grab_window, timestamp); meta_window_ungrab_all_keys (grab_info->grab_window, timestamp);
else else
meta_screen_ungrab_all_keys (display->grab_screen, timestamp); meta_screen_ungrab_all_keys (grab_info->grab_screen, timestamp);
} }
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
if (display->grab_sync_request_alarm != None) if (grab_info->grab_sync_request_alarm != None)
{ {
XSyncDestroyAlarm (display->xdisplay, XSyncDestroyAlarm (display->xdisplay,
display->grab_sync_request_alarm); grab_info->grab_sync_request_alarm);
display->grab_sync_request_alarm = None; grab_info->grab_sync_request_alarm = None;
} }
#endif /* HAVE_XSYNC */ #endif /* HAVE_XSYNC */
display->grab_window = NULL; if (grab_info->grab_resize_popup)
display->grab_screen = NULL; meta_ui_resize_popup_free (grab_info->grab_resize_popup);
display->grab_xwindow = None;
display->grab_tile_mode = META_TILE_NONE;
display->grab_op = META_GRAB_OP_NONE;
if (display->grab_resize_popup) if (grab_info->grab_resize_timeout_id)
{ {
meta_ui_resize_popup_free (display->grab_resize_popup); g_source_remove (grab_info->grab_resize_timeout_id);
display->grab_resize_popup = NULL; grab_info->grab_resize_timeout_id = 0;
} }
if (display->grab_resize_timeout_id) if (grab_info->grab_window != NULL)
{ grab_info->grab_window->cur_grab = NULL;
g_source_remove (display->grab_resize_timeout_id);
display->grab_resize_timeout_id = 0; meta_display_remove_grab_info (display, device);
} }
MetaGrabOp
meta_display_get_device_grab_op (MetaDisplay *display,
MetaDevice *device)
{
MetaGrabInfo *info;
info = meta_display_get_grab_info (display, device);
if (info)
return info->grab_op;
return META_GRAB_OP_NONE;
} }
/** /**
@ -3846,22 +3902,34 @@ meta_display_end_grab_op (MetaDisplay *display,
MetaGrabOp MetaGrabOp
meta_display_get_grab_op (MetaDisplay *display) meta_display_get_grab_op (MetaDisplay *display)
{ {
return display->grab_op; MetaDevice *device;
device = meta_device_map_lookup (display->device_map,
META_CORE_POINTER_ID);
return meta_display_get_device_grab_op (display, device);
} }
void void
meta_display_check_threshold_reached (MetaDisplay *display, meta_display_check_threshold_reached (MetaDisplay *display,
MetaDevice *device,
int x, int x,
int y) int y)
{ {
/* Don't bother doing the check again if we've already reached the threshold */ MetaGrabInfo *grab_info;
if (meta_prefs_get_raise_on_click () ||
display->grab_threshold_movement_reached) grab_info = meta_display_get_grab_info (display, device);
if (!grab_info)
return; return;
if (ABS (display->grab_initial_x - x) >= 8 || /* Don't bother doing the check again if we've already reached the threshold */
ABS (display->grab_initial_y - y) >= 8) if (meta_prefs_get_raise_on_click () ||
display->grab_threshold_movement_reached = TRUE; grab_info->grab_threshold_movement_reached)
return;
if (ABS (grab_info->grab_initial_x - x) >= 8 ||
ABS (grab_info->grab_initial_y - y) >= 8)
grab_info->grab_threshold_movement_reached = TRUE;
} }
static void static void
@ -5553,3 +5621,63 @@ meta_display_get_device_map (MetaDisplay *display)
return display->device_map; return display->device_map;
} }
MetaGrabInfo *
meta_display_create_grab_info (MetaDisplay *display,
MetaDevice *device)
{
MetaGrabInfo *grab_info;
gpointer key;
g_assert (meta_display_get_grab_info (display, device) == NULL);
grab_info = g_new0 (MetaGrabInfo, 1);
if (META_IS_DEVICE_KEYBOARD (device))
{
grab_info->grab_keyboard = device;
grab_info->grab_pointer = meta_device_get_paired_device (device);
}
else
{
grab_info->grab_pointer = device;
grab_info->grab_keyboard = meta_device_get_paired_device (device);
}
key = GINT_TO_POINTER (meta_device_get_id (grab_info->grab_pointer));
g_hash_table_insert (display->current_grabs, key, grab_info);
return grab_info;
}
void
meta_display_remove_grab_info (MetaDisplay *display,
MetaDevice *device)
{
g_hash_table_remove (display->current_grabs,
GINT_TO_POINTER (meta_device_get_id (device)));
device = meta_device_get_paired_device (device);
g_hash_table_remove (display->current_grabs,
GINT_TO_POINTER (meta_device_get_id (device)));
}
MetaGrabInfo *
meta_display_get_grab_info (MetaDisplay *display,
MetaDevice *device)
{
MetaGrabInfo *info;
info = g_hash_table_lookup (display->current_grabs,
GINT_TO_POINTER (meta_device_get_id (device)));
if (!info)
{
/* Try with the paired device */
device = meta_device_get_paired_device (device);
info = g_hash_table_lookup (display->current_grabs,
GINT_TO_POINTER (meta_device_get_id (device)));
}
return info;
}

View File

@ -30,10 +30,10 @@
/* A simple macro for whether a given window's edges are potentially /* A simple macro for whether a given window's edges are potentially
* relevant for resistance/snapping during a move/resize operation * relevant for resistance/snapping during a move/resize operation
*/ */
#define WINDOW_EDGES_RELEVANT(window, display) \ #define WINDOW_EDGES_RELEVANT(window, display, screen) \
meta_window_should_be_showing (window) && \ meta_window_should_be_showing (window) && \
window->screen == display->grab_screen && \ window->screen == screen && \
window != display->grab_window && \ window->cur_grab == NULL && \
window->type != META_WINDOW_DESKTOP && \ window->type != META_WINDOW_DESKTOP && \
window->type != META_WINDOW_MENU && \ window->type != META_WINDOW_MENU && \
window->type != META_WINDOW_SPLASHSCREEN window->type != META_WINDOW_SPLASHSCREEN
@ -44,8 +44,9 @@ struct ResistanceDataForAnEdge
guint timeout_id; guint timeout_id;
int timeout_edge_pos; int timeout_edge_pos;
gboolean timeout_over; gboolean timeout_over;
GSourceFunc timeout_func; MetaEdgeResistanceFunc timeout_func;
MetaWindow *window; MetaWindow *window;
MetaDevice *device;
int keyboard_buildup; int keyboard_buildup;
}; };
typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge; typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge;
@ -63,7 +64,9 @@ struct MetaEdgeResistanceData
ResistanceDataForAnEdge bottom_data; ResistanceDataForAnEdge bottom_data;
}; };
static void compute_resistance_and_snapping_edges (MetaDisplay *display); static MetaEdgeResistanceData *
compute_resistance_and_snapping_edges (MetaDisplay *display,
MetaScreen *screen);
/* !WARNING!: this function can return invalid indices (namely, either -1 or /* !WARNING!: this function can return invalid indices (namely, either -1 or
* edges->len); this is by design, but you need to remember this. * edges->len); this is by design, but you need to remember this.
@ -318,20 +321,22 @@ edge_resistance_timeout (gpointer data)
resistance_data->timeout_over = TRUE; resistance_data->timeout_over = TRUE;
resistance_data->timeout_id = 0; resistance_data->timeout_id = 0;
(*resistance_data->timeout_func)(resistance_data->window); (*resistance_data->timeout_func) (resistance_data->window,
resistance_data->device);
return FALSE; return FALSE;
} }
static int static int
apply_edge_resistance (MetaWindow *window, apply_edge_resistance (MetaWindow *window,
MetaDevice *device,
int old_pos, int old_pos,
int new_pos, int new_pos,
const MetaRectangle *old_rect, const MetaRectangle *old_rect,
const MetaRectangle *new_rect, const MetaRectangle *new_rect,
GArray *edges, GArray *edges,
ResistanceDataForAnEdge *resistance_data, ResistanceDataForAnEdge *resistance_data,
GSourceFunc timeout_func, MetaEdgeResistanceFunc timeout_func,
gboolean xdir, gboolean xdir,
gboolean keyboard_op) gboolean keyboard_op)
{ {
@ -445,6 +450,7 @@ apply_edge_resistance (MetaWindow *window,
resistance_data->timeout_over = FALSE; resistance_data->timeout_over = FALSE;
resistance_data->timeout_func = timeout_func; resistance_data->timeout_func = timeout_func;
resistance_data->window = window; resistance_data->window = window;
resistance_data->device = device;
} }
if (!resistance_data->timeout_over && if (!resistance_data->timeout_over &&
timeout_length_ms != 0) timeout_length_ms != 0)
@ -533,16 +539,14 @@ apply_edge_snapping (int old_pos,
* a proposed new position (ignoring edge resistance/snapping), and then * a proposed new position (ignoring edge resistance/snapping), and then
* applies edge resistance to EACH edge (separately) updating new_outer. * applies edge resistance to EACH edge (separately) updating new_outer.
* It returns true if new_outer is modified, false otherwise. * It returns true if new_outer is modified, false otherwise.
*
* display->grab_edge_resistance_data MUST already be setup or calling this
* function will cause a crash.
*/ */
static gboolean static gboolean
apply_edge_resistance_to_each_side (MetaDisplay *display, apply_edge_resistance_to_each_side (MetaDisplay *display,
MetaWindow *window, MetaWindow *window,
MetaDevice *device,
const MetaRectangle *old_outer, const MetaRectangle *old_outer,
MetaRectangle *new_outer, MetaRectangle *new_outer,
GSourceFunc timeout_func, MetaEdgeResistanceFunc timeout_func,
gboolean auto_snap, gboolean auto_snap,
gboolean keyboard_op, gboolean keyboard_op,
gboolean is_resize) gboolean is_resize)
@ -552,10 +556,11 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
gboolean modified; gboolean modified;
int new_left, new_right, new_top, new_bottom; int new_left, new_right, new_top, new_bottom;
if (display->grab_edge_resistance_data == NULL) edge_data = g_hash_table_lookup (display->edge_resistance_info,
compute_resistance_and_snapping_edges (display); window->screen);
edge_data = display->grab_edge_resistance_data; if (!edge_data)
edge_data = compute_resistance_and_snapping_edges (display, window->screen);
if (auto_snap) if (auto_snap)
{ {
@ -601,7 +606,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
if (!is_resize || window->size_hints.width_inc == 1) if (!is_resize || window->size_hints.width_inc == 1)
{ {
/* Now, apply the normal horizontal edge resistance */ /* Now, apply the normal horizontal edge resistance */
new_left = apply_edge_resistance (window, new_left = apply_edge_resistance (window, device,
BOX_LEFT (*old_outer), BOX_LEFT (*old_outer),
BOX_LEFT (*new_outer), BOX_LEFT (*new_outer),
old_outer, old_outer,
@ -611,7 +616,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
timeout_func, timeout_func,
TRUE, TRUE,
keyboard_op); keyboard_op);
new_right = apply_edge_resistance (window, new_right = apply_edge_resistance (window, device,
BOX_RIGHT (*old_outer), BOX_RIGHT (*old_outer),
BOX_RIGHT (*new_outer), BOX_RIGHT (*new_outer),
old_outer, old_outer,
@ -630,7 +635,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
/* Same for vertical resizes... */ /* Same for vertical resizes... */
if (!is_resize || window->size_hints.height_inc == 1) if (!is_resize || window->size_hints.height_inc == 1)
{ {
new_top = apply_edge_resistance (window, new_top = apply_edge_resistance (window, device,
BOX_TOP (*old_outer), BOX_TOP (*old_outer),
BOX_TOP (*new_outer), BOX_TOP (*new_outer),
old_outer, old_outer,
@ -640,7 +645,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
timeout_func, timeout_func,
FALSE, FALSE,
keyboard_op); keyboard_op);
new_bottom = apply_edge_resistance (window, new_bottom = apply_edge_resistance (window, device,
BOX_BOTTOM (*old_outer), BOX_BOTTOM (*old_outer),
BOX_BOTTOM (*new_outer), BOX_BOTTOM (*new_outer),
old_outer, old_outer,
@ -669,15 +674,20 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
} }
void void
meta_display_cleanup_edges (MetaDisplay *display) meta_display_cleanup_edges (MetaDisplay *display,
MetaScreen *screen)
{ {
guint i,j; guint i,j;
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data; MetaEdgeResistanceData *edge_data;
GHashTable *edges_to_be_freed; GHashTable *edges_to_be_freed;
edge_data = g_hash_table_lookup (display->edge_resistance_info, screen);
if (edge_data == NULL) /* Not currently cached */ if (edge_data == NULL) /* Not currently cached */
return; return;
g_hash_table_steal (display->edge_resistance_info, screen);
/* We first need to clean out any window edges */ /* We first need to clean out any window edges */
edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal, edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
g_free, NULL); g_free, NULL);
@ -750,8 +760,7 @@ meta_display_cleanup_edges (MetaDisplay *display)
edge_data->bottom_data.timeout_id != 0) edge_data->bottom_data.timeout_id != 0)
g_source_remove (edge_data->bottom_data.timeout_id); g_source_remove (edge_data->bottom_data.timeout_id);
g_free (display->grab_edge_resistance_data); g_free (edge_data);
display->grab_edge_resistance_data = NULL;
} }
static int static int
@ -763,8 +772,9 @@ stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
return meta_rectangle_edge_cmp_ignore_type (*a_edge, *b_edge); return meta_rectangle_edge_cmp_ignore_type (*a_edge, *b_edge);
} }
static void static MetaEdgeResistanceData *
cache_edges (MetaDisplay *display, cache_edges (MetaDisplay *display,
MetaScreen *screen,
GList *window_edges, GList *window_edges,
GList *monitor_edges, GList *monitor_edges,
GList *screen_edges) GList *screen_edges)
@ -848,9 +858,8 @@ cache_edges (MetaDisplay *display,
/* /*
* 2nd: Allocate the edges * 2nd: Allocate the edges
*/ */
g_assert (display->grab_edge_resistance_data == NULL); edge_data = g_new0 (MetaEdgeResistanceData, 1);
display->grab_edge_resistance_data = g_new0 (MetaEdgeResistanceData, 1);
edge_data = display->grab_edge_resistance_data;
edge_data->left_edges = g_array_sized_new (FALSE, edge_data->left_edges = g_array_sized_new (FALSE,
FALSE, FALSE,
sizeof(MetaEdge*), sizeof(MetaEdge*),
@ -917,21 +926,21 @@ cache_edges (MetaDisplay *display,
* avoided this sort by sticking them into the array with some simple * avoided this sort by sticking them into the array with some simple
* merging of the lists). * merging of the lists).
*/ */
g_array_sort (display->grab_edge_resistance_data->left_edges, g_array_sort (edge_data->left_edges,
stupid_sort_requiring_extra_pointer_dereference); stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->right_edges, g_array_sort (edge_data->right_edges,
stupid_sort_requiring_extra_pointer_dereference); stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->top_edges, g_array_sort (edge_data->top_edges,
stupid_sort_requiring_extra_pointer_dereference); stupid_sort_requiring_extra_pointer_dereference);
g_array_sort (display->grab_edge_resistance_data->bottom_edges, g_array_sort (edge_data->bottom_edges,
stupid_sort_requiring_extra_pointer_dereference); stupid_sort_requiring_extra_pointer_dereference);
return edge_data;
} }
static void static void
initialize_grab_edge_resistance_data (MetaDisplay *display) initialize_grab_edge_resistance_data (MetaEdgeResistanceData *edge_data)
{ {
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
edge_data->left_data.timeout_setup = FALSE; edge_data->left_data.timeout_setup = FALSE;
edge_data->right_data.timeout_setup = FALSE; edge_data->right_data.timeout_setup = FALSE;
edge_data->top_data.timeout_setup = FALSE; edge_data->top_data.timeout_setup = FALSE;
@ -943,8 +952,9 @@ initialize_grab_edge_resistance_data (MetaDisplay *display)
edge_data->bottom_data.keyboard_buildup = 0; edge_data->bottom_data.keyboard_buildup = 0;
} }
static void static MetaEdgeResistanceData *
compute_resistance_and_snapping_edges (MetaDisplay *display) compute_resistance_and_snapping_edges (MetaDisplay *display,
MetaScreen *screen)
{ {
GList *stacked_windows; GList *stacked_windows;
GList *cur_window_iter; GList *cur_window_iter;
@ -956,18 +966,17 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* in the layer that we are working on * in the layer that we are working on
*/ */
GSList *rem_windows, *rem_win_stacking; GSList *rem_windows, *rem_win_stacking;
MetaEdgeResistanceData *edge_data;
g_assert (display->grab_window != NULL);
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
"Computing edges to resist-movement or snap-to for %s.\n", "Computing edges to resist-movement or snap-to for screen %s.\n",
display->grab_window->desc); screen->screen_name);
/* /*
* 1st: Get the list of relevant windows, from bottom to top * 1st: Get the list of relevant windows, from bottom to top
*/ */
stacked_windows = stacked_windows =
meta_stack_list_windows (display->grab_screen->stack, meta_stack_list_windows (screen->stack, screen->active_workspace);
display->grab_screen->active_workspace);
/* /*
* 2nd: we need to separate that stacked list into a list of windows that * 2nd: we need to separate that stacked list into a list of windows that
@ -981,7 +990,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
while (cur_window_iter != NULL) while (cur_window_iter != NULL)
{ {
MetaWindow *cur_window = cur_window_iter->data; MetaWindow *cur_window = cur_window_iter->data;
if (WINDOW_EDGES_RELEVANT (cur_window, display)) if (WINDOW_EDGES_RELEVANT (cur_window, display, screen))
{ {
MetaRectangle *new_rect; MetaRectangle *new_rect;
new_rect = g_new (MetaRectangle, 1); new_rect = g_new (MetaRectangle, 1);
@ -1016,7 +1025,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* resistance (note that dock edges are considered screen edges * resistance (note that dock edges are considered screen edges
* which are handled separately * which are handled separately
*/ */
if (WINDOW_EDGES_RELEVANT (cur_window, display) && if (WINDOW_EDGES_RELEVANT (cur_window, display, screen) &&
cur_window->type != META_WINDOW_DOCK) cur_window->type != META_WINDOW_DOCK)
{ {
GList *new_edges; GList *new_edges;
@ -1028,7 +1037,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* by other windows or DOCKS, but that's handled below). * by other windows or DOCKS, but that's handled below).
*/ */
meta_rectangle_intersect (&cur_rect, meta_rectangle_intersect (&cur_rect,
&display->grab_screen->rect, &screen->rect,
&reduced); &reduced);
new_edges = NULL; new_edges = NULL;
@ -1123,16 +1132,18 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
* monitor edges in an array for quick access. Free the edges since * monitor edges in an array for quick access. Free the edges since
* they've been cached elsewhere. * they've been cached elsewhere.
*/ */
cache_edges (display, edge_data = cache_edges (display, screen,
edges, edges,
display->grab_screen->active_workspace->monitor_edges, screen->active_workspace->monitor_edges,
display->grab_screen->active_workspace->screen_edges); screen->active_workspace->screen_edges);
g_list_free (edges); g_list_free (edges);
/* /*
* 6th: Initialize the resistance timeouts and buildups * 6th: Initialize the resistance timeouts and buildups
*/ */
initialize_grab_edge_resistance_data (display); initialize_grab_edge_resistance_data (edge_data);
return edge_data;
} }
/* Note that old_[xy] and new_[xy] are with respect to inner positions of /* Note that old_[xy] and new_[xy] are with respect to inner positions of
@ -1140,15 +1151,17 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
*/ */
void void
meta_window_edge_resistance_for_move (MetaWindow *window, meta_window_edge_resistance_for_move (MetaWindow *window,
MetaDevice *device,
int old_x, int old_x,
int old_y, int old_y,
int *new_x, int *new_x,
int *new_y, int *new_y,
GSourceFunc timeout_func, MetaEdgeResistanceFunc timeout_func,
gboolean snap, gboolean snap,
gboolean is_keyboard_op) gboolean is_keyboard_op)
{ {
MetaRectangle old_outer, proposed_outer, new_outer; MetaRectangle old_outer, proposed_outer, new_outer;
MetaGrabInfo *grab_info;
gboolean is_resize; gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer); meta_window_get_outer_rect (window, &old_outer);
@ -1158,10 +1171,14 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
proposed_outer.y += (*new_y - old_y); proposed_outer.y += (*new_y - old_y);
new_outer = proposed_outer; new_outer = proposed_outer;
window->display->grab_last_user_action_was_snap = snap; grab_info = meta_display_get_grab_info (window->display, device);
g_assert (grab_info != NULL);
grab_info->grab_last_user_action_was_snap = snap;
is_resize = FALSE; is_resize = FALSE;
if (apply_edge_resistance_to_each_side (window->display, if (apply_edge_resistance_to_each_side (window->display,
window, window,
device,
&old_outer, &old_outer,
&new_outer, &new_outer,
timeout_func, timeout_func,
@ -1224,17 +1241,19 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
*/ */
void void
meta_window_edge_resistance_for_resize (MetaWindow *window, meta_window_edge_resistance_for_resize (MetaWindow *window,
MetaDevice *device,
int old_width, int old_width,
int old_height, int old_height,
int *new_width, int *new_width,
int *new_height, int *new_height,
int gravity, int gravity,
GSourceFunc timeout_func, MetaEdgeResistanceFunc timeout_func,
gboolean snap, gboolean snap,
gboolean is_keyboard_op) gboolean is_keyboard_op)
{ {
MetaRectangle old_outer, new_outer; MetaRectangle old_outer, new_outer;
int proposed_outer_width, proposed_outer_height; int proposed_outer_width, proposed_outer_height;
MetaGrabInfo *grab_info;
gboolean is_resize; gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer); meta_window_get_outer_rect (window, &old_outer);
@ -1246,10 +1265,14 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
proposed_outer_width, proposed_outer_width,
proposed_outer_height); proposed_outer_height);
window->display->grab_last_user_action_was_snap = snap; grab_info = meta_display_get_grab_info (window->display, device);
g_assert (grab_info != NULL);
grab_info->grab_last_user_action_was_snap = snap;
is_resize = TRUE; is_resize = TRUE;
if (apply_edge_resistance_to_each_side (window->display, if (apply_edge_resistance_to_each_side (window->display,
window, window,
device,
&old_outer, &old_outer,
&new_outer, &new_outer,
timeout_func, timeout_func,

View File

@ -26,21 +26,26 @@
#include "window-private.h" #include "window-private.h"
typedef gboolean (* MetaEdgeResistanceFunc) (MetaWindow *window,
MetaDevice *device);
void meta_window_edge_resistance_for_move (MetaWindow *window, void meta_window_edge_resistance_for_move (MetaWindow *window,
MetaDevice *device,
int old_x, int old_x,
int old_y, int old_y,
int *new_x, int *new_x,
int *new_y, int *new_y,
GSourceFunc timeout_func, MetaEdgeResistanceFunc func,
gboolean snap, gboolean snap,
gboolean is_keyboard_op); gboolean is_keyboard_op);
void meta_window_edge_resistance_for_resize (MetaWindow *window, void meta_window_edge_resistance_for_resize (MetaWindow *window,
MetaDevice *device,
int old_width, int old_width,
int old_height, int old_height,
int *new_width, int *new_width,
int *new_height, int *new_height,
int gravity, int gravity,
GSourceFunc timeout_func, MetaEdgeResistanceFunc func,
gboolean snap, gboolean snap,
gboolean is_keyboard_op); gboolean is_keyboard_op);

View File

@ -400,8 +400,7 @@ meta_frame_sync_to_window (MetaFrame *frame,
/* If we're interactively resizing the frame, repaint /* If we're interactively resizing the frame, repaint
* it immediately so we don't start to lag. * it immediately so we don't start to lag.
*/ */
if (frame->window->display->grab_window == if (frame->window->cur_grab != NULL)
frame->window)
meta_ui_repaint_frame (frame->window->screen->ui, meta_ui_repaint_frame (frame->window->screen->ui,
frame->xwindow); frame->xwindow);
} }

View File

@ -1470,16 +1470,20 @@ meta_display_process_key_event (MetaDisplay *display,
all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed; all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed;
if (all_keys_grabbed) if (all_keys_grabbed)
{ {
if (display->grab_op == META_GRAB_OP_NONE) MetaGrabInfo *grab_info;
grab_info = meta_display_get_grab_info (display, keyboard);
if (!grab_info)
return TRUE; return TRUE;
/* If we get here we have a global grab, because /* If we get here we have a global grab, because
* we're in some special keyboard mode such as window move * we're in some special keyboard mode such as window move
* mode. * mode.
*/ */
if (window ? (window == display->grab_window) : if (window ? (window == grab_info->grab_window) :
(screen == display->grab_screen)) (screen == grab_info->grab_screen))
{ {
switch (display->grab_op) switch (grab_info->grab_op)
{ {
case META_GRAB_OP_MOVING: case META_GRAB_OP_MOVING:
case META_GRAB_OP_RESIZING_SE: case META_GRAB_OP_RESIZING_SE:
@ -1546,8 +1550,8 @@ meta_display_process_key_event (MetaDisplay *display,
{ {
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Ending grab op %u on key event sym %s\n", "Ending grab op %u on key event sym %s\n",
display->grab_op, XKeysymToString (keysym)); grab_info->grab_op, XKeysymToString (keysym));
meta_display_end_grab_op (display, meta_display_end_grab_op (display, keyboard,
meta_input_event_get_time (display, event)); meta_input_event_get_time (display, event));
} }
@ -1578,12 +1582,19 @@ process_mouse_move_resize_grab (MetaDisplay *display,
if (keysym == XK_Escape) if (keysym == XK_Escape)
{ {
MetaGrabInfo *grab_info;
MetaDevice *device;
device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
g_assert (grab_info != NULL);
/* Hide the tiling preview if necessary */ /* Hide the tiling preview if necessary */
if (window->tile_mode != META_TILE_NONE) if (window->tile_mode != META_TILE_NONE)
meta_screen_tile_preview_hide (screen); meta_screen_tile_preview_hide (screen);
/* Restore the original tile mode */ /* Restore the original tile mode */
window->tile_mode = display->grab_tile_mode; window->tile_mode = grab_info->grab_tile_mode;
/* End move or resize and restore to original state. If the /* End move or resize and restore to original state. If the
* window was a maximized window that had been "shaken loose" we * window was a maximized window that had been "shaken loose" we
@ -1597,12 +1608,12 @@ process_mouse_move_resize_grab (MetaDisplay *display,
else if (window->tile_mode != META_TILE_NONE) else if (window->tile_mode != META_TILE_NONE)
meta_window_tile (window); meta_window_tile (window);
else else
meta_window_move_resize (display->grab_window, meta_window_move_resize (grab_info->grab_window,
TRUE, TRUE,
display->grab_initial_window_pos.x, grab_info->grab_initial_window_pos.x,
display->grab_initial_window_pos.y, grab_info->grab_initial_window_pos.y,
display->grab_initial_window_pos.width, grab_info->grab_initial_window_pos.width,
display->grab_initial_window_pos.height); grab_info->grab_initial_window_pos.height);
/* End grab */ /* End grab */
return FALSE; return FALSE;
@ -1653,6 +1664,13 @@ process_keyboard_move_grab (MetaDisplay *display,
if (keysym == XK_Escape) if (keysym == XK_Escape)
{ {
MetaGrabInfo *grab_info;
MetaDevice *device;
device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
g_assert (grab_info != NULL);
/* End move and restore to original state. If the window was a /* End move and restore to original state. If the window was a
* maximized window that had been "shaken loose" we need to * maximized window that had been "shaken loose" we need to
* remaximize it. In normal cases, we need to do a moveresize * remaximize it. In normal cases, we need to do a moveresize
@ -1663,12 +1681,12 @@ process_keyboard_move_grab (MetaDisplay *display,
META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_HORIZONTAL |
META_MAXIMIZE_VERTICAL); META_MAXIMIZE_VERTICAL);
else else
meta_window_move_resize (display->grab_window, meta_window_move_resize (grab_info->grab_window,
TRUE, TRUE,
display->grab_initial_window_pos.x, grab_info->grab_initial_window_pos.x,
display->grab_initial_window_pos.y, grab_info->grab_initial_window_pos.y,
display->grab_initial_window_pos.width, grab_info->grab_initial_window_pos.width,
display->grab_initial_window_pos.height); grab_info->grab_initial_window_pos.height);
} }
/* When moving by increments, we still snap to edges if the move /* When moving by increments, we still snap to edges if the move
@ -1715,13 +1733,16 @@ process_keyboard_move_grab (MetaDisplay *display,
if (handled) if (handled)
{ {
MetaRectangle old_rect; MetaRectangle old_rect;
MetaDevice *device;
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Computed new window location %d,%d due to keypress\n", "Computed new window location %d,%d due to keypress\n",
x, y); x, y);
device = meta_input_event_get_device (window->display, event);
meta_window_get_client_root_coords (window, &old_rect); meta_window_get_client_root_coords (window, &old_rect);
meta_window_edge_resistance_for_move (window, meta_window_edge_resistance_for_move (window, device,
old_rect.x, old_rect.x,
old_rect.y, old_rect.y,
&x, &x,
@ -1731,7 +1752,7 @@ process_keyboard_move_grab (MetaDisplay *display,
TRUE); TRUE);
meta_window_move (window, TRUE, x, y); meta_window_move (window, TRUE, x, y);
meta_window_update_keyboard_move (window); meta_window_update_keyboard_move (window, device);
} }
return handled; return handled;
@ -1744,32 +1765,37 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display,
XEvent *event, XEvent *event,
KeySym keysym) KeySym keysym)
{ {
MetaGrabInfo *grab_info;
MetaDevice *device;
gboolean handled; gboolean handled;
device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
handled = FALSE; handled = FALSE;
switch (display->grab_op) switch (grab_info->grab_op)
{ {
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
switch (keysym) switch (keysym)
{ {
case XK_Up: case XK_Up:
case XK_KP_Up: case XK_KP_Up:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
handled = TRUE; handled = TRUE;
break; break;
case XK_Down: case XK_Down:
case XK_KP_Down: case XK_KP_Down:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
handled = TRUE; handled = TRUE;
break; break;
case XK_Left: case XK_Left:
case XK_KP_Left: case XK_KP_Left:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
handled = TRUE; handled = TRUE;
break; break;
case XK_Right: case XK_Right:
case XK_KP_Right: case XK_KP_Right:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
handled = TRUE; handled = TRUE;
break; break;
} }
@ -1780,12 +1806,12 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display,
{ {
case XK_Left: case XK_Left:
case XK_KP_Left: case XK_KP_Left:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
handled = TRUE; handled = TRUE;
break; break;
case XK_Right: case XK_Right:
case XK_KP_Right: case XK_KP_Right:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
handled = TRUE; handled = TRUE;
break; break;
} }
@ -1796,12 +1822,12 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display,
{ {
case XK_Left: case XK_Left:
case XK_KP_Left: case XK_KP_Left:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
handled = TRUE; handled = TRUE;
break; break;
case XK_Right: case XK_Right:
case XK_KP_Right: case XK_KP_Right:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
handled = TRUE; handled = TRUE;
break; break;
} }
@ -1812,12 +1838,12 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display,
{ {
case XK_Up: case XK_Up:
case XK_KP_Up: case XK_KP_Up:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
handled = TRUE; handled = TRUE;
break; break;
case XK_Down: case XK_Down:
case XK_KP_Down: case XK_KP_Down:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
handled = TRUE; handled = TRUE;
break; break;
} }
@ -1828,12 +1854,12 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display,
{ {
case XK_Up: case XK_Up:
case XK_KP_Up: case XK_KP_Up:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
handled = TRUE; handled = TRUE;
break; break;
case XK_Down: case XK_Down:
case XK_KP_Down: case XK_KP_Down:
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; grab_info->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
handled = TRUE; handled = TRUE;
break; break;
} }
@ -1852,7 +1878,7 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display,
if (handled) if (handled)
{ {
meta_window_update_keyboard_resize (window, TRUE); meta_window_update_keyboard_resize (window, device, TRUE);
return TRUE; return TRUE;
} }
@ -1873,6 +1899,8 @@ process_keyboard_resize_grab (MetaDisplay *display,
gboolean smart_snap; gboolean smart_snap;
int gravity; int gravity;
guint keycode, state; guint keycode, state;
MetaDevice *device;
MetaGrabInfo *grab_info;
handled = FALSE; handled = FALSE;
@ -1887,15 +1915,18 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (is_modifier (display, keycode)) if (is_modifier (display, keycode))
return TRUE; return TRUE;
device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
if (keysym == XK_Escape) if (keysym == XK_Escape)
{ {
/* End resize and restore to original state. */ /* End resize and restore to original state. */
meta_window_move_resize (display->grab_window, meta_window_move_resize (grab_info->grab_window,
TRUE, TRUE,
display->grab_initial_window_pos.x, grab_info->grab_initial_window_pos.x,
display->grab_initial_window_pos.y, grab_info->grab_initial_window_pos.y,
display->grab_initial_window_pos.width, grab_info->grab_initial_window_pos.width,
display->grab_initial_window_pos.height); grab_info->grab_initial_window_pos.height);
return FALSE; return FALSE;
} }
@ -1907,7 +1938,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
width = window->rect.width; width = window->rect.width;
height = window->rect.height; height = window->rect.height;
gravity = meta_resize_gravity_from_grab_op (display->grab_op); gravity = meta_resize_gravity_from_grab_op (grab_info->grab_op);
smart_snap = (state & ShiftMask) != 0; smart_snap = (state & ShiftMask) != 0;
@ -2073,7 +2104,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
old_rect = window->rect; /* Don't actually care about x,y */ old_rect = window->rect; /* Don't actually care about x,y */
/* Do any edge resistance/snapping */ /* Do any edge resistance/snapping */
meta_window_edge_resistance_for_resize (window, meta_window_edge_resistance_for_resize (window, device,
old_rect.width, old_rect.width,
old_rect.height, old_rect.height,
&width, &width,
@ -2093,7 +2124,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
height, height,
gravity); gravity);
meta_window_update_keyboard_resize (window, FALSE); meta_window_update_keyboard_resize (window, device, FALSE);
} }
return handled; return handled;
@ -2101,15 +2132,20 @@ process_keyboard_resize_grab (MetaDisplay *display,
static gboolean static gboolean
end_keyboard_grab (MetaDisplay *display, end_keyboard_grab (MetaDisplay *display,
MetaDevice *device,
unsigned int keycode) unsigned int keycode)
{ {
MetaGrabInfo *grab_info;
grab_info = meta_display_get_grab_info (display, device);
#ifdef HAVE_XKB #ifdef HAVE_XKB
if (display->xkb_base_event_type > 0) if (display->xkb_base_event_type > 0)
{ {
unsigned int primary_modifier; unsigned int primary_modifier;
XkbStateRec state; XkbStateRec state;
primary_modifier = get_primary_modifier (display, display->grab_mask); primary_modifier = get_primary_modifier (display, grab_info->grab_mask);
XkbGetState (display->xdisplay, XkbUseCoreKbd, &state); XkbGetState (display->xdisplay, XkbUseCoreKbd, &state);
@ -2119,7 +2155,7 @@ end_keyboard_grab (MetaDisplay *display,
else else
#endif #endif
{ {
if (keycode_is_primary_modifier (display, keycode, display->grab_mask)) if (keycode_is_primary_modifier (display, keycode, grab_info->grab_mask))
return TRUE; return TRUE;
} }
@ -2139,8 +2175,16 @@ process_tab_grab (MetaDisplay *display,
gboolean key_used; gboolean key_used;
MetaWindow *prev_window; MetaWindow *prev_window;
guint evtype, keycode; guint evtype, keycode;
MetaDevice *device;
MetaGrabInfo *grab_info;
if (screen != display->grab_screen) device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
if (!grab_info)
return FALSE;
if (screen != grab_info->grab_screen)
return FALSE; return FALSE;
if (!meta_input_event_get_type (display, event, &evtype) || if (!meta_input_event_get_type (display, event, &evtype) ||
@ -2150,7 +2194,7 @@ process_tab_grab (MetaDisplay *display,
binding = display_get_keybinding (display, binding = display_get_keybinding (display,
keysym, keysym,
keycode, keycode,
display->grab_mask); grab_info->grab_mask);
if (binding) if (binding)
action = meta_prefs_get_keybinding_action (binding->name); action = meta_prefs_get_keybinding_action (binding->name);
else else
@ -2165,7 +2209,7 @@ process_tab_grab (MetaDisplay *display,
{ {
if (evtype == KeyRelease) if (evtype == KeyRelease)
{ {
if (end_keyboard_grab (display, keycode)) if (end_keyboard_grab (display, device, keycode))
{ {
invoke_handler_by_name (display, screen, "tab_popup_select", NULL, event); invoke_handler_by_name (display, screen, "tab_popup_select", NULL, event);
@ -2228,7 +2272,7 @@ process_tab_grab (MetaDisplay *display,
} }
if (evtype == KeyRelease && if (evtype == KeyRelease &&
end_keyboard_grab (display, keycode)) end_keyboard_grab (display, device, keycode))
{ {
/* We're done, move to the new window. */ /* We're done, move to the new window. */
MetaWindow *target_window; MetaWindow *target_window;
@ -2256,7 +2300,7 @@ process_tab_grab (MetaDisplay *display,
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Ending grab early so we can focus the target window\n"); "Ending grab early so we can focus the target window\n");
meta_display_end_grab_op (display, evtime); meta_display_end_grab_op (display, device, evtime);
return TRUE; /* we already ended the grab */ return TRUE; /* we already ended the grab */
} }
@ -2286,7 +2330,7 @@ process_tab_grab (MetaDisplay *display,
/* CYCLE_* are traditionally Escape-based actions, /* CYCLE_* are traditionally Escape-based actions,
* and should cancel traditionally Tab-based ones. * and should cancel traditionally Tab-based ones.
*/ */
switch (display->grab_op) switch (grab_info->grab_op)
{ {
case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
@ -2303,7 +2347,7 @@ process_tab_grab (MetaDisplay *display,
/* SWITCH_* are traditionally Tab-based actions, /* SWITCH_* are traditionally Tab-based actions,
* and should cancel traditionally Escape-based ones. * and should cancel traditionally Escape-based ones.
*/ */
switch (display->grab_op) switch (grab_info->grab_op)
{ {
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL: case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
case META_GRAB_OP_KEYBOARD_TABBING_DOCK: case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
@ -2314,7 +2358,7 @@ process_tab_grab (MetaDisplay *display,
* we'd previously raised and unminimized. * we'd previously raised and unminimized.
*/ */
meta_stack_set_positions (screen->stack, meta_stack_set_positions (screen->stack,
screen->display->grab_old_window_stacking); grab_info->grab_old_window_stacking);
if (prev_window && prev_window->tab_unminimized) if (prev_window && prev_window->tab_unminimized)
{ {
meta_window_minimize (prev_window); meta_window_minimize (prev_window);
@ -2327,7 +2371,7 @@ process_tab_grab (MetaDisplay *display,
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_GROUP: case META_KEYBINDING_ACTION_SWITCH_GROUP:
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
switch (display->grab_op) switch (grab_info->grab_op)
{ {
case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
case META_GRAB_OP_KEYBOARD_TABBING_GROUP: case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
@ -2408,7 +2452,7 @@ process_tab_grab (MetaDisplay *display,
MetaWindow *target_window; MetaWindow *target_window;
meta_stack_set_positions (screen->stack, meta_stack_set_positions (screen->stack,
display->grab_old_window_stacking); grab_info->grab_old_window_stacking);
target_window = meta_screen_tab_popup_get_selected (screen); target_window = meta_screen_tab_popup_get_selected (screen);
@ -2435,7 +2479,7 @@ process_tab_grab (MetaDisplay *display,
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Syncing to old stack positions.\n"); "Syncing to old stack positions.\n");
meta_stack_set_positions (screen->stack, meta_stack_set_positions (screen->stack,
screen->display->grab_old_window_stacking); grab_info->grab_old_window_stacking);
if (prev_window && prev_window->tab_unminimized) if (prev_window && prev_window->tab_unminimized)
{ {
@ -2834,9 +2878,14 @@ process_workspace_switch_grab (MetaDisplay *display,
{ {
MetaWorkspace *workspace; MetaWorkspace *workspace;
guint evtype, keycode; guint evtype, keycode;
MetaDevice *device;
MetaGrabInfo *grab_info;
Time evtime; Time evtime;
if (screen != display->grab_screen || !screen->ws_popup) device = meta_input_event_get_device (display, event);
grab_info = meta_display_get_grab_info (display, device);
if (screen != grab_info->grab_screen || !screen->ws_popup)
return FALSE; return FALSE;
if (!meta_input_event_get_type (display, event, &evtype) || if (!meta_input_event_get_type (display, event, &evtype) ||
@ -2846,7 +2895,7 @@ process_workspace_switch_grab (MetaDisplay *display,
evtime = meta_input_event_get_time (display, event); evtime = meta_input_event_get_time (display, event);
if (evtype == KeyRelease && if (evtype == KeyRelease &&
end_keyboard_grab (display, keycode)) end_keyboard_grab (display, device, keycode))
{ {
/* We're done, move to the new workspace. */ /* We're done, move to the new workspace. */
MetaWorkspace *target_workspace; MetaWorkspace *target_workspace;
@ -2860,7 +2909,7 @@ process_workspace_switch_grab (MetaDisplay *display,
{ {
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Ending grab so we can focus on the target workspace\n"); "Ending grab so we can focus on the target workspace\n");
meta_display_end_grab_op (display, evtime); meta_display_end_grab_op (display, device, evtime);
meta_topic (META_DEBUG_KEYBINDINGS, meta_topic (META_DEBUG_KEYBINDINGS,
"Focusing default window on target workspace\n"); "Focusing default window on target workspace\n");
@ -2896,7 +2945,7 @@ process_workspace_switch_grab (MetaDisplay *display,
action = meta_display_get_keybinding_action (display, action = meta_display_get_keybinding_action (display,
keycode, keycode,
display->grab_mask); grab_info->grab_mask);
switch (action) switch (action)
{ {
@ -3111,6 +3160,7 @@ do_choose_window (MetaDisplay *display,
{ {
MetaTabList type = binding->handler->data; MetaTabList type = binding->handler->data;
MetaWindow *initial_selection; MetaWindow *initial_selection;
MetaDevice *device;
guint state; guint state;
Time evtime; Time evtime;
@ -3125,6 +3175,7 @@ do_choose_window (MetaDisplay *display,
backward = !backward; backward = !backward;
evtime = meta_input_event_get_time (display, event); evtime = meta_input_event_get_time (display, event);
device = meta_input_event_get_device (display, event);
initial_selection = meta_display_get_tab_next (display, initial_selection = meta_display_get_tab_next (display,
type, type,
@ -3169,6 +3220,7 @@ do_choose_window (MetaDisplay *display,
if (!meta_display_begin_grab_op (display, if (!meta_display_begin_grab_op (display,
screen, screen,
NULL, NULL,
device,
show_popup ? show_popup ?
tab_op_from_tab_type (type) : tab_op_from_tab_type (type) :
cycle_op_from_tab_type (type), cycle_op_from_tab_type (type),
@ -3192,7 +3244,7 @@ do_choose_window (MetaDisplay *display,
"modifier was released prior to grab\n", "modifier was released prior to grab\n",
initial_selection->desc); initial_selection->desc);
meta_display_end_grab_op (display, evtime); meta_display_end_grab_op (display, device, evtime);
display->mouse_mode = FALSE; display->mouse_mode = FALSE;
meta_window_activate (initial_selection, evtime); meta_window_activate (initial_selection, evtime);
return; return;
@ -3391,6 +3443,7 @@ handle_begin_move (MetaDisplay *display,
if (window->has_move_func) if (window->has_move_func)
{ {
meta_window_begin_grab_op (window, meta_window_begin_grab_op (window,
meta_input_event_get_device (display, event),
META_GRAB_OP_KEYBOARD_MOVING, META_GRAB_OP_KEYBOARD_MOVING,
FALSE, FALSE,
meta_input_event_get_time (display, event)); meta_input_event_get_time (display, event));
@ -3408,6 +3461,7 @@ handle_begin_resize (MetaDisplay *display,
if (window->has_resize_func) if (window->has_resize_func)
{ {
meta_window_begin_grab_op (window, meta_window_begin_grab_op (window,
meta_input_event_get_device (display, event),
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
FALSE, FALSE,
meta_input_event_get_time (display, event)); meta_input_event_get_time (display, event));
@ -3564,6 +3618,7 @@ handle_workspace_switch (MetaDisplay *display,
unsigned int grab_mask; unsigned int grab_mask;
MetaWorkspace *next; MetaWorkspace *next;
gboolean grabbed_before_release; gboolean grabbed_before_release;
MetaDevice *device;
guint state; guint state;
Time evtime; Time evtime;
@ -3578,10 +3633,12 @@ handle_workspace_switch (MetaDisplay *display,
/* FIXME should we use binding->mask ? */ /* FIXME should we use binding->mask ? */
grab_mask = state & ~(display->ignored_modifier_mask); grab_mask = state & ~(display->ignored_modifier_mask);
evtime = meta_input_event_get_time (display, event); evtime = meta_input_event_get_time (display, event);
device = meta_input_event_get_device (display, event);
if (!meta_display_begin_grab_op (display, if (!meta_display_begin_grab_op (display,
screen, screen,
NULL, NULL,
device,
META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING, META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
FALSE, FALSE,
FALSE, FALSE,
@ -3605,7 +3662,7 @@ handle_workspace_switch (MetaDisplay *display,
* release event. Must end grab before we can switch * release event. Must end grab before we can switch
* spaces. * spaces.
*/ */
meta_display_end_grab_op (display, evtime); meta_display_end_grab_op (display, device, evtime);
} }
meta_workspace_activate (next, evtime); meta_workspace_activate (next, evtime);

View File

@ -1859,9 +1859,17 @@ static gboolean
meta_screen_tile_preview_update_timeout (gpointer data) meta_screen_tile_preview_update_timeout (gpointer data)
{ {
MetaScreen *screen = data; MetaScreen *screen = data;
MetaWindow *window = screen->display->grab_window; MetaWindow *window = NULL;
gboolean composited = screen->display->compositor != NULL; gboolean composited = screen->display->compositor != NULL;
gboolean needs_preview = FALSE; gboolean needs_preview = FALSE;
MetaGrabInfo *grab_info;
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;
screen->tile_preview_timeout_id = 0; screen->tile_preview_timeout_id = 0;
@ -1905,7 +1913,7 @@ meta_screen_tile_preview_update_timeout (gpointer data)
MetaRectangle tile_rect; MetaRectangle tile_rect;
meta_window_get_current_tile_area (window, &tile_rect); meta_window_get_current_tile_area (window, &tile_rect);
meta_tile_preview_show (screen->tile_preview, &tile_rect); meta_tile_preview_show (screen->tile_preview, pointer, &tile_rect);
} }
else else
meta_tile_preview_hide (screen->tile_preview); meta_tile_preview_hide (screen->tile_preview);

View File

@ -395,6 +395,9 @@ struct _MetaWindow
/* Focused window that is (directly or indirectly) attached to this one */ /* Focused window that is (directly or indirectly) attached to this one */
MetaWindow *attached_focus_window; MetaWindow *attached_focus_window;
/* Current grab op for this window, or NULL */
MetaGrabInfo *cur_grab;
}; };
struct _MetaWindowClass struct _MetaWindowClass
@ -613,13 +616,16 @@ void meta_window_free_delete_dialog (MetaWindow *window);
void meta_window_begin_grab_op (MetaWindow *window, void meta_window_begin_grab_op (MetaWindow *window,
MetaDevice *device,
MetaGrabOp op, MetaGrabOp op,
gboolean frame_action, gboolean frame_action,
guint32 timestamp); guint32 timestamp);
void meta_window_update_keyboard_resize (MetaWindow *window, void meta_window_update_keyboard_resize (MetaWindow *window,
MetaDevice *device,
gboolean update_cursor); gboolean update_cursor);
void meta_window_update_keyboard_move (MetaWindow *window); void meta_window_update_keyboard_move (MetaWindow *window,
MetaDevice *device);
void meta_window_update_layer (MetaWindow *window); void meta_window_update_layer (MetaWindow *window);
@ -643,4 +649,6 @@ void meta_window_update_on_all_workspaces (MetaWindow *window);
void meta_window_propagate_focus_appearance (MetaWindow *window, void meta_window_propagate_focus_appearance (MetaWindow *window,
gboolean focused); gboolean focused);
MetaDevice * meta_window_guess_grab_pointer (MetaWindow *window);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -538,6 +538,8 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
MetaWorkspaceLayout layout1, layout2; MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space; gint num_workspaces, current_space, new_space;
MetaMotionDirection direction; MetaMotionDirection direction;
MetaGrabInfo *grab_info;
GHashTableIter iter;
meta_verbose ("Activating workspace %d\n", meta_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace)); meta_workspace_index (workspace));
@ -547,7 +549,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/* Free any cached pointers to the workspaces's edges from /* Free any cached pointers to the workspaces's edges from
* a current resize or move operation */ * a current resize or move operation */
meta_display_cleanup_edges (workspace->screen->display); meta_display_cleanup_edges (workspace->screen->display, workspace->screen);
if (workspace->screen->active_workspace) if (workspace->screen->active_workspace)
workspace_switch_sound (workspace->screen->active_workspace, workspace); workspace_switch_sound (workspace->screen->active_workspace, workspace);
@ -570,9 +572,21 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
return; return;
move_window = NULL; move_window = NULL;
if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING) /* FIXME: not quite multidevice friendly, but the whole
move_window = workspace->screen->display->grab_window; * "move window to another workspace" isn't.
*/
g_hash_table_iter_init (&iter, workspace->screen->display->current_grabs);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info))
{
if (grab_info->grab_op == META_GRAB_OP_MOVING ||
grab_info->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
{
move_window = grab_info->grab_window;
break;
}
}
if (move_window != NULL) if (move_window != NULL)
{ {
@ -774,7 +788,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
/* If we are in the middle of a resize or move operation, we /* If we are in the middle of a resize or move operation, we
* might have cached pointers to the workspace's edges */ * might have cached pointers to the workspace's edges */
if (workspace == workspace->screen->active_workspace) if (workspace == workspace->screen->active_workspace)
meta_display_cleanup_edges (workspace->screen->display); meta_display_cleanup_edges (workspace->screen->display, workspace->screen);
g_free (workspace->work_area_monitor); g_free (workspace->work_area_monitor);
workspace->work_area_monitor = NULL; workspace->work_area_monitor = NULL;

View File

@ -112,6 +112,7 @@ MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
gboolean meta_display_begin_grab_op (MetaDisplay *display, gboolean meta_display_begin_grab_op (MetaDisplay *display,
MetaScreen *screen, MetaScreen *screen,
MetaWindow *window, MetaWindow *window,
MetaDevice *device,
MetaGrabOp op, MetaGrabOp op,
gboolean pointer_already_grabbed, gboolean pointer_already_grabbed,
gboolean frame_action, gboolean frame_action,
@ -121,10 +122,14 @@ gboolean meta_display_begin_grab_op (MetaDisplay *display,
int root_x, int root_x,
int root_y); int root_y);
void meta_display_end_grab_op (MetaDisplay *display, void meta_display_end_grab_op (MetaDisplay *display,
MetaDevice *device,
guint32 timestamp); guint32 timestamp);
MetaGrabOp meta_display_get_grab_op (MetaDisplay *display); MetaGrabOp meta_display_get_grab_op (MetaDisplay *display);
MetaGrabOp meta_display_get_device_grab_op (MetaDisplay *display,
MetaDevice *device);
MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay *display, MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay *display,
unsigned int keycode, unsigned int keycode,
unsigned long mask); unsigned long mask);

View File

@ -1555,6 +1555,8 @@ meta_frames_button_press_event (GtkWidget *widget,
MetaFrames *frames; MetaFrames *frames;
MetaFrameControl control; MetaFrameControl control;
Display *display; Display *display;
GdkDevice *device;
int device_id;
frames = META_FRAMES (widget); frames = META_FRAMES (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
@ -1589,6 +1591,9 @@ meta_frames_button_press_event (GtkWidget *widget,
if (control == META_FRAME_CONTROL_CLIENT_AREA) if (control == META_FRAME_CONTROL_CLIENT_AREA)
return FALSE; /* not on the frame, just passed through from client */ return FALSE; /* not on the frame, just passed through from client */
device = gdk_event_get_device ((GdkEvent *) event);
device_id = gdk_x11_device_get_id (device);
/* We want to shade even if we have a GrabOp, since we'll have a move grab /* We want to shade even if we have a GrabOp, since we'll have a move grab
* if we double click the titlebar. * if we double click the titlebar.
*/ */
@ -1596,11 +1601,11 @@ meta_frames_button_press_event (GtkWidget *widget,
event->button == 1 && event->button == 1 &&
event->type == GDK_2BUTTON_PRESS) event->type == GDK_2BUTTON_PRESS)
{ {
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
return meta_frame_double_click_event (frame, event); return meta_frame_double_click_event (frame, event);
} }
if (meta_core_get_grab_op (display) != if (meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL) !=
META_GRAB_OP_NONE) META_GRAB_OP_NONE)
return FALSE; /* already up to something */ return FALSE; /* already up to something */
@ -1661,6 +1666,7 @@ meta_frames_button_press_event (GtkWidget *widget,
meta_core_begin_grab_op (display, meta_core_begin_grab_op (display,
frame->xwindow, frame->xwindow,
device_id,
op, op,
TRUE, TRUE,
TRUE, TRUE,
@ -1746,6 +1752,7 @@ meta_frames_button_press_event (GtkWidget *widget,
meta_core_begin_grab_op (display, meta_core_begin_grab_op (display,
frame->xwindow, frame->xwindow,
device_id,
op, op,
TRUE, TRUE,
TRUE, TRUE,
@ -1768,6 +1775,7 @@ meta_frames_button_press_event (GtkWidget *widget,
{ {
meta_core_begin_grab_op (display, meta_core_begin_grab_op (display,
frame->xwindow, frame->xwindow,
device_id,
META_GRAB_OP_MOVING, META_GRAB_OP_MOVING,
TRUE, TRUE,
TRUE, TRUE,
@ -1791,28 +1799,28 @@ meta_frames_button_press_event (GtkWidget *widget,
} }
void void
meta_frames_notify_menu_hide (MetaFrames *frames) meta_frames_notify_menu_hide (MetaFrames *frames,
Window client_xwindow)
{ {
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
if (meta_core_get_grab_op (display) == Window frame_xwindow;
int device_id;
frame_xwindow = meta_core_get_frame (display, client_xwindow);
if (frame_xwindow != None &&
meta_core_frame_has_grab (display, frame_xwindow, &device_id, NULL) ==
META_GRAB_OP_CLICKING_MENU) META_GRAB_OP_CLICKING_MENU)
{
Window grab_frame;
grab_frame = meta_core_get_grab_frame (display);
if (grab_frame != None)
{ {
MetaUIFrame *frame; MetaUIFrame *frame;
frame = meta_frames_lookup_window (frames, grab_frame); frame = meta_frames_lookup_window (frames, frame_xwindow);
if (frame) if (frame)
{ {
redraw_control (frames, frame, redraw_control (frames, frame,
META_FRAME_CONTROL_MENU); META_FRAME_CONTROL_MENU);
meta_core_end_grab_op (display, CurrentTime); meta_core_end_grab_op (display, device_id, CurrentTime);
}
} }
} }
} }
@ -1825,6 +1833,9 @@ meta_frames_button_release_event (GtkWidget *widget,
MetaFrames *frames; MetaFrames *frames;
MetaGrabOp op; MetaGrabOp op;
Display *display; Display *display;
int grab_button;
GdkDevice *device;
int device_id, grab_device_id;
frames = META_FRAMES (widget); frames = META_FRAMES (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
@ -1835,17 +1846,21 @@ meta_frames_button_release_event (GtkWidget *widget,
clear_tip (frames); clear_tip (frames);
op = meta_core_get_grab_op (display); op = meta_core_frame_has_grab (display, frame->xwindow,
&grab_device_id, &grab_button);
if (op == META_GRAB_OP_NONE) device = gdk_event_get_device ((GdkEvent *) event);
device_id = gdk_x11_device_get_id (device);
if (op == META_GRAB_OP_NONE ||
grab_device_id != device_id)
return FALSE; return FALSE;
/* We only handle the releases we handled the presses for (things /* We only handle the releases we handled the presses for (things
* involving frame controls). Window ops that don't require a * involving frame controls). Window ops that don't require a
* frame are handled in the Xlib part of the code, display.c/window.c * frame are handled in the Xlib part of the code, display.c/window.c
*/ */
if (frame->xwindow == meta_core_get_grab_frame (display) && if (((int) event->button) == grab_button)
((int) event->button) == meta_core_get_grab_button (display))
{ {
MetaFrameControl control; MetaFrameControl control;
@ -1857,7 +1872,7 @@ meta_frames_button_release_event (GtkWidget *widget,
if (control == META_FRAME_CONTROL_MINIMIZE) if (control == META_FRAME_CONTROL_MINIMIZE)
meta_core_minimize (display, frame->xwindow); meta_core_minimize (display, frame->xwindow);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_MAXIMIZE: case META_GRAB_OP_CLICKING_MAXIMIZE:
@ -1869,67 +1884,67 @@ meta_frames_button_release_event (GtkWidget *widget,
event->time); event->time);
meta_core_maximize (display, frame->xwindow); meta_core_maximize (display, frame->xwindow);
} }
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_UNMAXIMIZE: case META_GRAB_OP_CLICKING_UNMAXIMIZE:
if (control == META_FRAME_CONTROL_UNMAXIMIZE) if (control == META_FRAME_CONTROL_UNMAXIMIZE)
meta_core_unmaximize (display, frame->xwindow); meta_core_unmaximize (display, frame->xwindow);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_DELETE: case META_GRAB_OP_CLICKING_DELETE:
if (control == META_FRAME_CONTROL_DELETE) if (control == META_FRAME_CONTROL_DELETE)
meta_core_delete (display, frame->xwindow, event->time); meta_core_delete (display, frame->xwindow, event->time);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_MENU: case META_GRAB_OP_CLICKING_MENU:
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_SHADE: case META_GRAB_OP_CLICKING_SHADE:
if (control == META_FRAME_CONTROL_SHADE) if (control == META_FRAME_CONTROL_SHADE)
meta_core_shade (display, frame->xwindow, event->time); meta_core_shade (display, frame->xwindow, event->time);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_UNSHADE: case META_GRAB_OP_CLICKING_UNSHADE:
if (control == META_FRAME_CONTROL_UNSHADE) if (control == META_FRAME_CONTROL_UNSHADE)
meta_core_unshade (display, frame->xwindow, event->time); meta_core_unshade (display, frame->xwindow, event->time);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_ABOVE: case META_GRAB_OP_CLICKING_ABOVE:
if (control == META_FRAME_CONTROL_ABOVE) if (control == META_FRAME_CONTROL_ABOVE)
meta_core_make_above (display, frame->xwindow); meta_core_make_above (display, frame->xwindow);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_UNABOVE: case META_GRAB_OP_CLICKING_UNABOVE:
if (control == META_FRAME_CONTROL_UNABOVE) if (control == META_FRAME_CONTROL_UNABOVE)
meta_core_unmake_above (display, frame->xwindow); meta_core_unmake_above (display, frame->xwindow);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_STICK: case META_GRAB_OP_CLICKING_STICK:
if (control == META_FRAME_CONTROL_STICK) if (control == META_FRAME_CONTROL_STICK)
meta_core_stick (display, frame->xwindow); meta_core_stick (display, frame->xwindow);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
case META_GRAB_OP_CLICKING_UNSTICK: case META_GRAB_OP_CLICKING_UNSTICK:
if (control == META_FRAME_CONTROL_UNSTICK) if (control == META_FRAME_CONTROL_UNSTICK)
meta_core_unstick (display, frame->xwindow); meta_core_unstick (display, frame->xwindow);
meta_core_end_grab_op (display, event->time); meta_core_end_grab_op (display, device_id, event->time);
break; break;
default: default:
@ -2075,7 +2090,7 @@ meta_frames_motion_notify_event (GtkWidget *widget,
frames->last_motion_frame = frame; frames->last_motion_frame = frame;
grab_op = meta_core_get_grab_op (display); grab_op = meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL);
switch (grab_op) switch (grab_op)
{ {
@ -2472,7 +2487,6 @@ meta_frames_paint (MetaFrames *frames,
GdkPixbuf *icon; GdkPixbuf *icon;
int w, h; int w, h;
MetaButtonState button_states[META_BUTTON_TYPE_LAST]; MetaButtonState button_states[META_BUTTON_TYPE_LAST];
Window grab_frame;
int i; int i;
MetaButtonLayout button_layout; MetaButtonLayout button_layout;
MetaGrabOp grab_op; MetaGrabOp grab_op;
@ -2484,10 +2498,7 @@ meta_frames_paint (MetaFrames *frames,
for (i = 0; i < META_BUTTON_TYPE_LAST; i++) for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
button_states[i] = META_BUTTON_STATE_NORMAL; button_states[i] = META_BUTTON_STATE_NORMAL;
grab_frame = meta_core_get_grab_frame (display); grab_op = meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL);
grab_op = meta_core_get_grab_op (display);
if (grab_frame != frame->xwindow)
grab_op = META_GRAB_OP_NONE;
/* Set prelight state */ /* Set prelight state */
switch (frame->prelit_control) switch (frame->prelit_control)

View File

@ -163,7 +163,8 @@ void meta_frames_move_resize_frame (MetaFrames *frames,
void meta_frames_queue_draw (MetaFrames *frames, void meta_frames_queue_draw (MetaFrames *frames,
Window xwindow); Window xwindow);
void meta_frames_notify_menu_hide (MetaFrames *frames); void meta_frames_notify_menu_hide (MetaFrames *frames,
Window client_xwindow);
Window meta_frames_get_moving_frame (MetaFrames *frames); Window meta_frames_get_moving_frame (MetaFrames *frames);

View File

@ -137,7 +137,7 @@ menu_closed (GtkMenu *widget,
menu = data; menu = data;
meta_frames_notify_menu_hide (menu->frames); meta_frames_notify_menu_hide (menu->frames, menu->client_xwindow);
(* menu->func) (menu, (* menu->func) (menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
menu->client_xwindow, menu->client_xwindow,
@ -157,7 +157,7 @@ activate_cb (GtkWidget *menuitem, gpointer data)
md = data; md = data;
meta_frames_notify_menu_hide (md->menu->frames); meta_frames_notify_menu_hide (md->menu->frames, md->menu->client_xwindow);
(* md->menu->func) (md->menu, (* md->menu->func) (md->menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
md->menu->client_xwindow, md->menu->client_xwindow,

View File

@ -171,6 +171,7 @@ meta_tile_preview_free (MetaTilePreview *preview)
void void
meta_tile_preview_show (MetaTilePreview *preview, meta_tile_preview_show (MetaTilePreview *preview,
MetaDevice *pointer,
MetaRectangle *tile_rect) MetaRectangle *tile_rect)
{ {
GdkWindow *window; GdkWindow *window;
@ -187,6 +188,7 @@ meta_tile_preview_show (MetaTilePreview *preview,
window = gtk_widget_get_window (preview->preview_window); window = gtk_widget_get_window (preview->preview_window);
meta_core_lower_beneath_grab_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), meta_core_lower_beneath_grab_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
GDK_WINDOW_XID (window), GDK_WINDOW_XID (window),
meta_device_get_id (pointer),
gtk_get_current_event_time ()); gtk_get_current_event_time ());
old_rect.x = old_rect.y = 0; old_rect.x = old_rect.y = 0;

View File

@ -24,6 +24,7 @@
#define META_TILE_PREVIEW_H #define META_TILE_PREVIEW_H
#include <meta/boxes.h> #include <meta/boxes.h>
#include <meta/device.h>
typedef struct _MetaTilePreview MetaTilePreview; typedef struct _MetaTilePreview MetaTilePreview;
@ -31,6 +32,7 @@ MetaTilePreview *meta_tile_preview_new (int screen_number,
gboolean composited); gboolean composited);
void meta_tile_preview_free (MetaTilePreview *preview); void meta_tile_preview_free (MetaTilePreview *preview);
void meta_tile_preview_show (MetaTilePreview *preview, void meta_tile_preview_show (MetaTilePreview *preview,
MetaDevice *pointer,
MetaRectangle *rect); MetaRectangle *rect);
void meta_tile_preview_hide (MetaTilePreview *preview); void meta_tile_preview_hide (MetaTilePreview *preview);
Window meta_tile_preview_get_xwindow (MetaTilePreview *preview, Window meta_tile_preview_get_xwindow (MetaTilePreview *preview,