Compare commits
13 Commits
wip/xinput
...
wip/multit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e8682d607 | ||
|
|
de0d9e4da8 | ||
|
|
900b91f385 | ||
|
|
7971d5a871 | ||
|
|
c8f0a136cc | ||
|
|
3b578c2983 | ||
|
|
0142e34af8 | ||
|
|
6439856800 | ||
|
|
704e2320c3 | ||
|
|
bbc69c4220 | ||
|
|
6a03efe435 | ||
|
|
85c1058c94 | ||
|
|
91f87e8173 |
@@ -27,6 +27,7 @@
|
||||
#include "core.h"
|
||||
#include "frame.h"
|
||||
#include "workspace-private.h"
|
||||
#include "input-events.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/errors.h>
|
||||
|
||||
@@ -866,7 +867,8 @@ meta_core_select_events (Display *xdisplay,
|
||||
XISelectEvents (xdisplay, xwindow, &mask, 1);
|
||||
|
||||
/* Unset any input event so they are only handled via XInput2 */
|
||||
evmask &= ~(KeyPressMask | KeyReleaseMask |
|
||||
evmask &= ~(META_INPUT_TOUCH_EVENTS_MASK |
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
PointerMotionMask | PointerMotionHintMask |
|
||||
|
||||
@@ -76,6 +76,10 @@ struct _MetaDeviceMapClass
|
||||
Window xwindow,
|
||||
guint n_button,
|
||||
guint modifiers);
|
||||
void (* grab_touch) (MetaDeviceMap *pointer,
|
||||
Window xwindow);
|
||||
void (* ungrab_touch) (MetaDeviceMap *pointer,
|
||||
Window xwindow);
|
||||
};
|
||||
|
||||
GType meta_device_map_get_type (void) G_GNUC_CONST;
|
||||
@@ -108,4 +112,9 @@ void meta_device_map_ungrab_button (MetaDeviceMap *device_map,
|
||||
guint n_button,
|
||||
guint modifiers);
|
||||
|
||||
void meta_device_map_grab_touch (MetaDeviceMap *device_map,
|
||||
Window xwindow);
|
||||
void meta_device_map_ungrab_touch (MetaDeviceMap *device_map,
|
||||
Window xwindow);
|
||||
|
||||
#endif /* META_DEVICE_MAP_PRIVATE_H */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "device-map-xi2.h"
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include "devices-xi2.h"
|
||||
#include "input-events.h"
|
||||
|
||||
#define XINPUT2_VERSION_MAJOR 2
|
||||
#define XINPUT2_VERSION_MINOR 2
|
||||
@@ -123,26 +124,23 @@ meta_device_map_xi2_ungrab_button (MetaDeviceMap *device_map,
|
||||
n_button, xwindow, 1, &mods);
|
||||
}
|
||||
|
||||
static void
|
||||
add_device_from_info (MetaDeviceMap *device_map,
|
||||
gint use,
|
||||
gint device_id)
|
||||
static MetaDevice *
|
||||
create_device_from_info (MetaDeviceMap *device_map,
|
||||
gint use,
|
||||
gint device_id)
|
||||
{
|
||||
MetaDevice *device;
|
||||
MetaDevice *device = NULL;
|
||||
MetaDisplay *display;
|
||||
|
||||
display = meta_device_map_get_display (device_map);
|
||||
|
||||
if (use == XIMasterPointer)
|
||||
if (use == XIMasterPointer ||
|
||||
use == XISlavePointer)
|
||||
device = meta_device_pointer_xi2_new (display, device_id);
|
||||
else if (use == XIMasterKeyboard)
|
||||
device = meta_device_keyboard_xi2_new (display, device_id);
|
||||
|
||||
if (device)
|
||||
{
|
||||
meta_device_map_add_device (device_map, device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -175,15 +173,27 @@ meta_device_map_xi2_constructed (GObject *object)
|
||||
* detached slave devices are left for applications
|
||||
* to handle.
|
||||
*/
|
||||
info = XIQueryDevice (display->xdisplay, XIAllMasterDevices, &n_devices);
|
||||
info = XIQueryDevice (display->xdisplay, XIAllDevices, &n_devices);
|
||||
pairs = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < n_devices; i++)
|
||||
{
|
||||
add_device_from_info (device_map, info[i].use, info[i].deviceid);
|
||||
g_hash_table_insert (pairs,
|
||||
GINT_TO_POINTER (info[i].deviceid),
|
||||
GINT_TO_POINTER (info[i].attachment));
|
||||
MetaDevice *device;
|
||||
|
||||
device = create_device_from_info (device_map, info[i].use,
|
||||
info[i].deviceid);
|
||||
if (device)
|
||||
{
|
||||
meta_device_map_add_device (device_map, device);
|
||||
|
||||
if (info[i].use == XIMasterPointer ||
|
||||
info[i].use == XIMasterKeyboard)
|
||||
g_hash_table_insert (pairs,
|
||||
GINT_TO_POINTER (info[i].deviceid),
|
||||
GINT_TO_POINTER (info[i].attachment));
|
||||
|
||||
g_object_unref (device);
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_foreach (pairs, pair_devices, device_map);
|
||||
@@ -192,6 +202,45 @@ meta_device_map_xi2_constructed (GObject *object)
|
||||
XIFreeDeviceInfo (info);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_device_map_xi2_grab_touch (MetaDeviceMap *device_map,
|
||||
Window xwindow)
|
||||
{
|
||||
XIGrabModifiers unused = { 0 };
|
||||
MetaDisplay *display;
|
||||
XIEventMask mask;
|
||||
|
||||
display = meta_device_map_get_display (device_map);
|
||||
|
||||
g_message ("Grabbing passively on touch begin\n");
|
||||
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
mask.mask = meta_device_xi2_translate_event_mask (META_INPUT_TOUCH_EVENTS_MASK |
|
||||
ButtonPressMask |
|
||||
ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
KeyPressMask |
|
||||
KeyReleaseMask,
|
||||
&mask.mask_len);
|
||||
XIGrabTouchBegin (display->xdisplay,
|
||||
XIAllMasterDevices,
|
||||
xwindow, True,
|
||||
&mask, 1, &unused);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_device_map_xi2_ungrab_touch (MetaDeviceMap *device_map,
|
||||
Window xwindow)
|
||||
{
|
||||
XIGrabModifiers unused = { 0 };
|
||||
MetaDisplay *display;
|
||||
|
||||
display = meta_device_map_get_display (device_map);
|
||||
XIUngrabTouchBegin (display->xdisplay,
|
||||
XIAllMasterDevices,
|
||||
xwindow, 0, &unused);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_device_map_xi2_class_init (MetaDeviceMapXI2Class *klass)
|
||||
{
|
||||
@@ -204,6 +253,8 @@ meta_device_map_xi2_class_init (MetaDeviceMapXI2Class *klass)
|
||||
device_map_class->ungrab_key = meta_device_map_xi2_ungrab_key;
|
||||
device_map_class->grab_button = meta_device_map_xi2_grab_button;
|
||||
device_map_class->ungrab_button = meta_device_map_xi2_ungrab_button;
|
||||
device_map_class->grab_touch = meta_device_map_xi2_grab_touch;
|
||||
device_map_class->ungrab_touch = meta_device_map_xi2_ungrab_touch;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -237,16 +288,23 @@ meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map,
|
||||
|
||||
for (i = 0; i < xev->num_info; i++)
|
||||
{
|
||||
if (xev->info[i].flags & XIMasterAdded)
|
||||
if (xev->info[i].flags & XIMasterAdded ||
|
||||
xev->info[i].flags & XISlaveAdded)
|
||||
{
|
||||
add_device_from_info (META_DEVICE_MAP (device_map),
|
||||
xev->info[i].use,
|
||||
xev->info[i].deviceid);
|
||||
g_hash_table_insert (pairs,
|
||||
GINT_TO_POINTER (xev->info[i].deviceid),
|
||||
GINT_TO_POINTER (xev->info[i].attachment));
|
||||
MetaDevice *device;
|
||||
|
||||
device = create_device_from_info (META_DEVICE_MAP (device_map),
|
||||
xev->info[i].use,
|
||||
xev->info[i].deviceid);
|
||||
|
||||
if (device &&
|
||||
xev->info[i].flags & XIMasterAdded)
|
||||
g_hash_table_insert (pairs,
|
||||
GINT_TO_POINTER (xev->info[i].deviceid),
|
||||
GINT_TO_POINTER (xev->info[i].attachment));
|
||||
}
|
||||
else if (xev->info[i].flags & XIMasterRemoved)
|
||||
else if (xev->info[i].flags & XIMasterRemoved ||
|
||||
xev->info[i].flags & XISlaveRemoved)
|
||||
{
|
||||
MetaDevice *device;
|
||||
|
||||
|
||||
@@ -388,3 +388,33 @@ meta_device_map_ungrab_button (MetaDeviceMap *device_map,
|
||||
if (klass->ungrab_button)
|
||||
(klass->ungrab_button) (device_map, xwindow, n_button, modifiers);
|
||||
}
|
||||
|
||||
void
|
||||
meta_device_map_grab_touch (MetaDeviceMap *device_map,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaDeviceMapClass *klass;
|
||||
|
||||
g_return_if_fail (META_IS_DEVICE_MAP (device_map));
|
||||
g_return_if_fail (xwindow != None);
|
||||
|
||||
klass = META_DEVICE_MAP_GET_CLASS (device_map);
|
||||
|
||||
if (klass->grab_touch)
|
||||
(klass->grab_touch) (device_map, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_device_map_ungrab_touch (MetaDeviceMap *device_map,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaDeviceMapClass *klass;
|
||||
|
||||
g_return_if_fail (META_IS_DEVICE_MAP (device_map));
|
||||
g_return_if_fail (xwindow != None);
|
||||
|
||||
klass = META_DEVICE_MAP_GET_CLASS (device_map);
|
||||
|
||||
if (klass->ungrab_touch)
|
||||
(klass->ungrab_touch) (device_map, xwindow);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "devices-xi2.h"
|
||||
#include "display-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "input-events.h"
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
/* Common functions */
|
||||
@@ -97,6 +98,13 @@ meta_device_xi2_translate_event_mask (guint evmask,
|
||||
XISetMask (mask, XI_FocusOut);
|
||||
}
|
||||
|
||||
if (evmask & META_INPUT_TOUCH_EVENTS_MASK)
|
||||
{
|
||||
XISetMask (mask, XI_TouchBegin);
|
||||
XISetMask (mask, XI_TouchEnd);
|
||||
XISetMask (mask, XI_TouchUpdate);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
|
||||
|
||||
typedef struct _MetaGrabInfo MetaGrabInfo;
|
||||
typedef struct _MetaFocusInfo MetaFocusInfo;
|
||||
typedef struct _MetaTouchInfo MetaTouchInfo;
|
||||
|
||||
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
@@ -151,6 +152,18 @@ struct _MetaFocusInfo
|
||||
guint32 last_focus_time;
|
||||
};
|
||||
|
||||
struct _MetaTouchInfo
|
||||
{
|
||||
gdouble root_x;
|
||||
gdouble root_y;
|
||||
|
||||
gdouble initial_root_x;
|
||||
gdouble initial_root_y;
|
||||
|
||||
guint notified : 1;
|
||||
guint use_for_hotspot : 1;
|
||||
};
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -425,6 +438,10 @@ void meta_display_grab_window_buttons (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
void meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
void meta_display_grab_window_touches (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
void meta_display_ungrab_window_touches (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_display_grab_focus_window_button (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
@@ -2043,6 +2043,14 @@ event_callback (XEvent *event,
|
||||
filter_out_event = bypass_compositor = TRUE;
|
||||
break;
|
||||
case ButtonPress:
|
||||
if (window &&
|
||||
meta_input_event_get_touch_id (display, event, NULL))
|
||||
{
|
||||
meta_window_update_touch (window, event);
|
||||
filter_out_event = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
meta_input_event_get_button (display, event, &n_button);
|
||||
meta_input_event_get_state (display, event, &state);
|
||||
meta_input_event_get_coordinates (display, event,
|
||||
@@ -2259,6 +2267,14 @@ event_callback (XEvent *event,
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if (window &&
|
||||
meta_input_event_get_touch_id (display, event, NULL))
|
||||
{
|
||||
meta_window_end_touch (window, event);
|
||||
filter_out_event = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
break;
|
||||
|
||||
@@ -2270,6 +2286,14 @@ event_callback (XEvent *event,
|
||||
meta_window_handle_mouse_grab_op_event (window, event);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if (window &&
|
||||
meta_input_event_get_touch_id (display, event, NULL))
|
||||
{
|
||||
meta_window_update_touch (window, event);
|
||||
filter_out_event = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (grab_info && grab_info->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
break;
|
||||
|
||||
@@ -4372,6 +4396,36 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_grab_window_touches (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (!window->frame)
|
||||
return;
|
||||
|
||||
meta_error_trap_push_with_return (display);
|
||||
meta_device_map_grab_touch (display->device_map,
|
||||
window->frame->xwindow);
|
||||
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_verbose ("Unable to add a passive touch grab on window '%s'\n",
|
||||
window->desc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_ungrab_window_touches (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (!window->frame)
|
||||
return;
|
||||
|
||||
meta_device_map_ungrab_touch (display->device_map,
|
||||
window->frame->xwindow);
|
||||
}
|
||||
|
||||
/* Grab buttons we only grab while unfocused in click-to-focus mode */
|
||||
#define MAX_FOCUS_BUTTON 4
|
||||
void
|
||||
|
||||
@@ -86,6 +86,26 @@ meta_input_event_get_type (MetaDisplay *display,
|
||||
case XI_Leave:
|
||||
type = LeaveNotify;
|
||||
break;
|
||||
case XI_TouchBegin:
|
||||
type = ButtonPress;
|
||||
break;
|
||||
case XI_TouchEnd:
|
||||
type = ButtonRelease;
|
||||
break;
|
||||
case XI_TouchUpdate:
|
||||
if (((XIDeviceEvent *) xev)->flags & XITouchPendingEnd)
|
||||
{
|
||||
/* Consider these events like TouchEnd, as we
|
||||
* could still need to call XIAllowTouchEvents()
|
||||
* for this touch sequence so we get the real
|
||||
* TouchEnd event, handling this event type the
|
||||
* second time it arrives should be a NO-OP.
|
||||
*/
|
||||
type = ButtonRelease;
|
||||
}
|
||||
else
|
||||
type = MotionNotify;
|
||||
break;
|
||||
default:
|
||||
retval = FALSE;
|
||||
break;
|
||||
@@ -137,6 +157,63 @@ meta_input_event_is_type (MetaDisplay *display,
|
||||
return (type == ev_type);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_input_event_ignore (MetaDisplay *display,
|
||||
XEvent *ev)
|
||||
{
|
||||
if (ev->type == GenericEvent &&
|
||||
ev->xcookie.extension == display->xinput2_opcode)
|
||||
{
|
||||
XIEvent *xev;
|
||||
|
||||
g_assert (display->have_xinput2 == TRUE);
|
||||
xev = (XIEvent *) ev->xcookie.data;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
if (((XIDeviceEvent *) xev)->flags & XIPointerEmulated)
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_input_event_get_touch_id (MetaDisplay *display,
|
||||
XEvent *ev,
|
||||
guint *touch_id)
|
||||
{
|
||||
if (ev->type == GenericEvent &&
|
||||
ev->xcookie.extension == display->xinput2_opcode)
|
||||
{
|
||||
XIEvent *xev;
|
||||
|
||||
g_assert (display->have_xinput2 == TRUE);
|
||||
xev = (XIEvent *) ev->xcookie.data;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
if (touch_id)
|
||||
*touch_id = ((XIDeviceEvent *) xev)->detail;
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Window
|
||||
meta_input_event_get_window (MetaDisplay *display,
|
||||
XEvent *ev)
|
||||
@@ -159,6 +236,9 @@ meta_input_event_get_window (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
return ((XIDeviceEvent *) xev)->event;
|
||||
case XI_FocusIn:
|
||||
case XI_FocusOut:
|
||||
@@ -195,6 +275,9 @@ meta_input_event_get_root_window (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
return ((XIDeviceEvent *) xev)->root;
|
||||
case XI_FocusIn:
|
||||
case XI_FocusOut:
|
||||
@@ -250,6 +333,9 @@ meta_input_event_get_time (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
return ((XIDeviceEvent *) xev)->time;
|
||||
case XI_FocusIn:
|
||||
case XI_FocusOut:
|
||||
@@ -312,6 +398,9 @@ meta_input_event_get_coordinates (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
{
|
||||
XIDeviceEvent *event = (XIDeviceEvent *) xev;
|
||||
|
||||
@@ -422,6 +511,9 @@ meta_input_event_get_state (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
s = ((XIDeviceEvent *) xev)->mods.effective;
|
||||
break;
|
||||
case XI_FocusIn:
|
||||
@@ -643,6 +735,9 @@ meta_input_event_get_device (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
return meta_device_map_lookup (display->device_map,
|
||||
((XIDeviceEvent *) xev)->deviceid);
|
||||
case XI_FocusIn:
|
||||
@@ -675,3 +770,44 @@ meta_input_event_get_device (MetaDisplay *display,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaDevice *
|
||||
meta_input_event_get_source_device (MetaDisplay *display,
|
||||
XEvent *ev)
|
||||
{
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (ev->type == GenericEvent &&
|
||||
ev->xcookie.extension == display->xinput2_opcode)
|
||||
{
|
||||
XIEvent *xev;
|
||||
|
||||
g_assert (display->have_xinput2 == TRUE);
|
||||
|
||||
xev = (XIEvent *) ev->xcookie.data;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
case XI_TouchUpdate:
|
||||
return meta_device_map_lookup (display->device_map,
|
||||
((XIDeviceEvent *) xev)->sourceid);
|
||||
case XI_FocusIn:
|
||||
case XI_FocusOut:
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
return meta_device_map_lookup (display->device_map,
|
||||
((XIEnterEvent *) xev)->sourceid);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
#include "display-private.h"
|
||||
#include <meta/device-map.h>
|
||||
|
||||
/* Add an extra flag for touch events in
|
||||
* evmasks, an arbitrarily high bit is taken.
|
||||
*/
|
||||
#define META_INPUT_TOUCH_EVENTS_MASK (1L<<31)
|
||||
|
||||
gboolean meta_input_event_get_type (MetaDisplay *display,
|
||||
XEvent *ev,
|
||||
guint *ev_type);
|
||||
@@ -42,6 +47,10 @@ gboolean meta_input_event_is_type (MetaDisplay *display,
|
||||
XEvent *ev,
|
||||
guint ev_type);
|
||||
|
||||
gboolean meta_input_event_get_touch_id (MetaDisplay *display,
|
||||
XEvent *ev,
|
||||
guint *touch_id);
|
||||
|
||||
Window meta_input_event_get_window (MetaDisplay *display,
|
||||
XEvent *ev);
|
||||
Window meta_input_event_get_root_window (MetaDisplay *display,
|
||||
@@ -73,6 +82,7 @@ gboolean meta_input_event_get_crossing_details (MetaDisplay *display,
|
||||
|
||||
MetaDevice *meta_input_event_get_device (MetaDisplay *display,
|
||||
XEvent *ev);
|
||||
|
||||
MetaDevice *meta_input_event_get_source_device (MetaDisplay *display,
|
||||
XEvent *ev);
|
||||
|
||||
#endif /* META_EVENT_H */
|
||||
|
||||
@@ -106,6 +106,7 @@ static void handle_workspace_switch (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy);
|
||||
|
||||
static gboolean process_mouse_move_resize_grab (MetaDisplay *display,
|
||||
@@ -1365,6 +1366,7 @@ invoke_handler (MetaDisplay *display,
|
||||
MetaKeyHandler *handler,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaDevice *device,
|
||||
MetaKeyBinding *binding)
|
||||
|
||||
{
|
||||
@@ -1374,6 +1376,7 @@ invoke_handler (MetaDisplay *display,
|
||||
window : NULL,
|
||||
event,
|
||||
binding,
|
||||
device,
|
||||
handler->user_data);
|
||||
else
|
||||
(* handler->default_func) (display, screen,
|
||||
@@ -1381,6 +1384,7 @@ invoke_handler (MetaDisplay *display,
|
||||
window: NULL,
|
||||
event,
|
||||
binding,
|
||||
device,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -1389,13 +1393,14 @@ invoke_handler_by_name (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
const char *handler_name,
|
||||
MetaWindow *window,
|
||||
XEvent *event)
|
||||
XEvent *event,
|
||||
MetaDevice *device)
|
||||
{
|
||||
MetaKeyHandler *handler;
|
||||
|
||||
handler = HANDLER (handler_name);
|
||||
if (handler)
|
||||
invoke_handler (display, screen, handler, window, event, NULL);
|
||||
invoke_handler (display, screen, handler, window, event, device, NULL);
|
||||
}
|
||||
|
||||
/* now called from only one place, may be worth merging */
|
||||
@@ -1409,6 +1414,7 @@ process_event (MetaKeyBinding *bindings,
|
||||
KeySym keysym,
|
||||
gboolean on_window)
|
||||
{
|
||||
MetaDevice *device;
|
||||
guint evtype, keycode, state;
|
||||
int i;
|
||||
|
||||
@@ -1421,6 +1427,8 @@ process_event (MetaKeyBinding *bindings,
|
||||
if (evtype == KeyRelease)
|
||||
return FALSE;
|
||||
|
||||
device = meta_input_event_get_device (display, event);;
|
||||
|
||||
/*
|
||||
* TODO: This would be better done with a hash table;
|
||||
* it doesn't suit to use O(n) for such a common operation.
|
||||
@@ -1460,7 +1468,7 @@ process_event (MetaKeyBinding *bindings,
|
||||
*/
|
||||
display->allow_terminal_deactivation = TRUE;
|
||||
|
||||
invoke_handler (display, screen, handler, window, event, &bindings[i]);
|
||||
invoke_handler (display, screen, handler, window, event, device, &bindings[i]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2380,7 +2388,7 @@ process_tab_grab (MetaDisplay *display,
|
||||
{
|
||||
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, device);
|
||||
|
||||
/* We return FALSE to end the grab; if the handler ended the grab itself
|
||||
* that will be a noop. If the handler didn't end the grab, then it's a
|
||||
@@ -2417,7 +2425,7 @@ process_tab_grab (MetaDisplay *display,
|
||||
binding->handler->func &&
|
||||
binding->handler->func != binding->handler->default_func)
|
||||
{
|
||||
invoke_handler (display, screen, binding->handler, NULL, event, binding);
|
||||
invoke_handler (display, screen, binding->handler, NULL, event, device, binding);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
@@ -2436,7 +2444,7 @@ process_tab_grab (MetaDisplay *display,
|
||||
}
|
||||
|
||||
/* Some unhandled key press */
|
||||
invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event);
|
||||
invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event, device);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2662,11 +2670,12 @@ process_tab_grab (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_switch_to_workspace (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint which = binding->handler->data;
|
||||
MetaWorkspace *workspace;
|
||||
@@ -2683,8 +2692,8 @@ handle_switch_to_workspace (MetaDisplay *display,
|
||||
* Note that we're the only caller of that function, so perhaps
|
||||
* we should merge with it.
|
||||
*/
|
||||
handle_workspace_switch (display, screen, event_window, event, binding,
|
||||
dummy);
|
||||
handle_workspace_switch (display, screen, event_window, event,
|
||||
binding, device, dummy);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2703,11 +2712,12 @@ handle_switch_to_workspace (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_maximize_vertically (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_resize_func)
|
||||
{
|
||||
@@ -2720,11 +2730,12 @@ handle_maximize_vertically (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_maximize_horizontally (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_resize_func)
|
||||
{
|
||||
@@ -2788,6 +2799,7 @@ handle_move_to_corner_nw (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, FALSE, dummy);
|
||||
@@ -2799,6 +2811,7 @@ handle_move_to_corner_ne (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, FALSE, dummy);
|
||||
@@ -2810,6 +2823,7 @@ handle_move_to_corner_sw (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, TRUE, dummy);
|
||||
@@ -2821,6 +2835,7 @@ handle_move_to_corner_se (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, TRUE, dummy);
|
||||
@@ -2832,6 +2847,7 @@ handle_move_to_side_n (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, FALSE, dummy);
|
||||
@@ -2843,6 +2859,7 @@ handle_move_to_side_s (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, TRUE, dummy);
|
||||
@@ -2854,6 +2871,7 @@ handle_move_to_side_e (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, TRUE, FALSE, dummy);
|
||||
@@ -2865,6 +2883,7 @@ handle_move_to_side_w (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, FALSE, FALSE, dummy);
|
||||
@@ -2876,6 +2895,7 @@ handle_move_to_center (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
MetaRectangle work_area;
|
||||
@@ -3029,11 +3049,12 @@ process_workspace_switch_grab (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_show_desktop (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
Time evtime;
|
||||
|
||||
@@ -3056,11 +3077,12 @@ handle_show_desktop (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_panel (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
MetaKeyBindingAction action = binding->handler->data;
|
||||
Atom action_atom;
|
||||
@@ -3111,16 +3133,15 @@ handle_panel (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_activate_window_menu (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
MetaFocusInfo *focus_info;
|
||||
MetaDevice *device;
|
||||
|
||||
device = meta_input_event_get_device (display, event);
|
||||
focus_info = meta_display_get_focus_info (display, device);
|
||||
|
||||
if (focus_info->focus_window &&
|
||||
@@ -3210,8 +3231,8 @@ do_choose_window (MetaDisplay *display,
|
||||
if (state & ShiftMask)
|
||||
backward = !backward;
|
||||
|
||||
evtime = meta_input_event_get_time (display, event);
|
||||
device = meta_input_event_get_device (display, event);
|
||||
evtime = meta_input_event_get_time (display, event);
|
||||
|
||||
initial_selection = meta_display_get_tab_next (display,
|
||||
type,
|
||||
@@ -3302,11 +3323,12 @@ do_choose_window (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_switch (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
||||
|
||||
@@ -3316,11 +3338,12 @@ handle_switch (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_cycle (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
||||
|
||||
@@ -3334,6 +3357,7 @@ handle_tab_popup_select (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
/* Stub for custom handlers; no default implementation */
|
||||
@@ -3345,6 +3369,7 @@ handle_tab_popup_cancel (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
/* Stub for custom handlers; no default implementation */
|
||||
@@ -3356,6 +3381,7 @@ handle_toggle_fullscreen (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->fullscreen)
|
||||
@@ -3370,6 +3396,7 @@ handle_toggle_above (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->wm_state_above)
|
||||
@@ -3384,26 +3411,26 @@ handle_toggle_tiled (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
MetaTileMode mode = binding->handler->data;
|
||||
MetaDevice *device = meta_input_event_get_device (display, event);
|
||||
MetaDevice *pointer = meta_device_get_paired_device (device);
|
||||
|
||||
if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) ||
|
||||
(META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT))
|
||||
{
|
||||
window->tile_monitor_number = window->saved_maximize ? window->monitor->number
|
||||
: -1;
|
||||
: -1;
|
||||
window->tile_mode = window->saved_maximize ? META_TILE_MAXIMIZED
|
||||
: META_TILE_NONE;
|
||||
: META_TILE_NONE;
|
||||
|
||||
if (window->saved_maximize)
|
||||
meta_window_maximize (window, META_MAXIMIZE_VERTICAL |
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
else
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL |
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
}
|
||||
else if (meta_window_can_tile_side_by_side (window, pointer))
|
||||
{
|
||||
@@ -3422,11 +3449,12 @@ handle_toggle_tiled (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_toggle_maximized (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (META_WINDOW_MAXIMIZED (window))
|
||||
meta_window_unmaximize (window,
|
||||
@@ -3444,6 +3472,7 @@ handle_maximize (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_maximize_func)
|
||||
@@ -3458,6 +3487,7 @@ handle_unmaximize (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->maximized_vertically || window->maximized_horizontally)
|
||||
@@ -3472,6 +3502,7 @@ handle_toggle_shaded (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
Time evtime;
|
||||
@@ -3490,6 +3521,7 @@ handle_close (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_close_func)
|
||||
@@ -3504,6 +3536,7 @@ handle_minimize (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_minimize_func)
|
||||
@@ -3516,6 +3549,7 @@ handle_begin_move (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_move_func)
|
||||
@@ -3534,6 +3568,7 @@ handle_begin_resize (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_resize_func)
|
||||
@@ -3548,11 +3583,12 @@ handle_begin_resize (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_toggle_on_all_workspaces (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->on_all_workspaces_requested)
|
||||
meta_window_unstick (window);
|
||||
@@ -3562,10 +3598,11 @@ handle_toggle_on_all_workspaces (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_move_to_workspace (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint which = binding->handler->data;
|
||||
@@ -3621,6 +3658,7 @@ handle_raise_or_lower (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
/* Get window at pointer */
|
||||
@@ -3668,6 +3706,7 @@ handle_raise (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
meta_window_raise (window);
|
||||
@@ -3679,24 +3718,24 @@ handle_lower (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
meta_window_lower (window);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_workspace_switch (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint motion = binding->handler->data;
|
||||
unsigned int grab_mask;
|
||||
MetaWorkspace *next;
|
||||
gboolean grabbed_before_release;
|
||||
MetaDevice *device;
|
||||
guint state;
|
||||
Time evtime;
|
||||
|
||||
@@ -3711,7 +3750,6 @@ handle_workspace_switch (MetaDisplay *display,
|
||||
/* FIXME should we use binding->mask ? */
|
||||
grab_mask = state & ~(display->ignored_modifier_mask);
|
||||
evtime = meta_input_event_get_time (display, event);
|
||||
device = meta_input_event_get_device (display, event);
|
||||
|
||||
if (!meta_display_begin_grab_op (display,
|
||||
screen,
|
||||
@@ -3752,10 +3790,11 @@ handle_workspace_switch (MetaDisplay *display,
|
||||
|
||||
static void
|
||||
handle_set_spew_mark (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer dummy)
|
||||
{
|
||||
meta_verbose ("-- MARK MARK MARK MARK --\n");
|
||||
|
||||
@@ -340,6 +340,9 @@ struct _MetaWindow
|
||||
/* if TRUE, window didn't yet get the FocusIn for window->focus_keyboard */
|
||||
guint expecting_focus_in : 1;
|
||||
|
||||
/* if TRUE, tiling mode is held regardless of newer touch updates */
|
||||
guint touch_hold_tiling_mode : 1;
|
||||
|
||||
/* Keyboard currently owning the window focus, or NULL */
|
||||
MetaDevice *focus_keyboard;
|
||||
|
||||
@@ -429,6 +432,12 @@ struct _MetaWindow
|
||||
|
||||
/* Focus info if the window is focused, or NULL */
|
||||
MetaFocusInfo *cur_focus;
|
||||
|
||||
GHashTable *cur_touches;
|
||||
gdouble initial_touch_area_width;
|
||||
gdouble initial_touch_area_height;
|
||||
gdouble cur_touch_area_width;
|
||||
gdouble cur_touch_area_height;
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
@@ -675,4 +684,9 @@ MetaDevice * meta_window_get_client_pointer (MetaWindow *window);
|
||||
|
||||
MetaDevice * meta_window_guess_grab_pointer (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_update_touch (MetaWindow *window,
|
||||
XEvent *event);
|
||||
void meta_window_end_touch (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
|
||||
#define N_TOUCHES_FOR_GRAB 3
|
||||
#define TOUCH_THRESHOLD 16
|
||||
#define TILING_ZOOM_FACTOR 1.5
|
||||
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
/* Windows that unmaximize to a size bigger than that fraction of the workarea
|
||||
@@ -240,6 +244,9 @@ meta_window_finalize (GObject *object)
|
||||
if (window->menu)
|
||||
meta_ui_window_menu_free (window->menu);
|
||||
|
||||
if (window->cur_touches)
|
||||
g_hash_table_destroy (window->cur_touches);
|
||||
|
||||
meta_icon_cache_free (&window->icon_cache);
|
||||
|
||||
g_free (window->sm_client_id);
|
||||
@@ -1297,6 +1304,14 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
meta_display_grab_focus_window_button (window->display, window);
|
||||
}
|
||||
|
||||
if (window->frame &&
|
||||
(window->type == META_WINDOW_NORMAL ||
|
||||
window->type == META_WINDOW_DIALOG ||
|
||||
window->type == META_WINDOW_MODAL_DIALOG))
|
||||
{
|
||||
meta_display_grab_window_touches (window->display, window);
|
||||
}
|
||||
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
window->type == META_WINDOW_DOCK)
|
||||
{
|
||||
@@ -1905,6 +1920,7 @@ meta_window_unmanage (MetaWindow *window,
|
||||
meta_window_ungrab_keys (window);
|
||||
meta_display_ungrab_window_buttons (window->display, window->xwindow);
|
||||
meta_display_ungrab_focus_window_button (window->display, window);
|
||||
meta_display_ungrab_window_touches (window->display, window);
|
||||
|
||||
meta_display_unregister_x_window (window->display, window->xwindow);
|
||||
|
||||
@@ -8815,6 +8831,30 @@ update_move (MetaWindow *window,
|
||||
else if (meta_window_can_tile_maximized (window) &&
|
||||
y >= monitor->rect.y && y <= work_area.y)
|
||||
window->tile_mode = META_TILE_MAXIMIZED;
|
||||
else if (window->cur_touches &&
|
||||
g_hash_table_size (window->cur_touches) >= N_TOUCHES_FOR_GRAB)
|
||||
{
|
||||
if (!window->touch_hold_tiling_mode)
|
||||
{
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
|
||||
if (window->cur_touch_area_height >
|
||||
window->initial_touch_area_height * TILING_ZOOM_FACTOR)
|
||||
{
|
||||
if (window->cur_touch_area_width >
|
||||
window->initial_touch_area_width * TILING_ZOOM_FACTOR &&
|
||||
meta_window_can_tile_maximized (window))
|
||||
window->tile_mode = META_TILE_MAXIMIZED;
|
||||
else if (meta_window_can_tile_side_by_side (window, device))
|
||||
{
|
||||
if (x < (monitor->rect.x + (monitor->rect.width / 2)))
|
||||
window->tile_mode = META_TILE_LEFT;
|
||||
else
|
||||
window->tile_mode = META_TILE_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
|
||||
@@ -11110,3 +11150,347 @@ meta_window_guess_grab_pointer (MetaWindow *window)
|
||||
|
||||
return meta_window_get_client_pointer (window);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gdouble top_left_x;
|
||||
gdouble top_left_y;
|
||||
gdouble bottom_right_x;
|
||||
gdouble bottom_right_y;
|
||||
gboolean only_hotspot;
|
||||
} BoundingRectCoords;
|
||||
|
||||
static void
|
||||
calculate_touch_bounding_rect (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
BoundingRectCoords *bounding_rect = user_data;
|
||||
MetaTouchInfo *touch_info = value;
|
||||
|
||||
if (bounding_rect->only_hotspot &&
|
||||
!touch_info->use_for_hotspot)
|
||||
return;
|
||||
|
||||
if (touch_info->root_x < bounding_rect->top_left_x)
|
||||
bounding_rect->top_left_x = touch_info->root_x;
|
||||
if (touch_info->root_x > bounding_rect->bottom_right_x)
|
||||
bounding_rect->bottom_right_x = touch_info->root_x;
|
||||
|
||||
if (touch_info->root_y < bounding_rect->top_left_y)
|
||||
bounding_rect->top_left_y = touch_info->root_y;
|
||||
if (touch_info->root_y > bounding_rect->bottom_right_y)
|
||||
bounding_rect->bottom_right_y = touch_info->root_y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_get_touch_area (MetaWindow *window,
|
||||
gdouble *center_x,
|
||||
gdouble *center_y,
|
||||
gdouble *width,
|
||||
gdouble *height)
|
||||
{
|
||||
if (g_hash_table_size (window->cur_touches) == 0)
|
||||
return FALSE;
|
||||
|
||||
if (width || height)
|
||||
{
|
||||
BoundingRectCoords bounding_rect = { DBL_MAX, DBL_MAX,
|
||||
DBL_MIN, DBL_MIN,
|
||||
FALSE };
|
||||
|
||||
g_hash_table_foreach (window->cur_touches,
|
||||
calculate_touch_bounding_rect,
|
||||
&bounding_rect);
|
||||
|
||||
if (width)
|
||||
*width = bounding_rect.bottom_right_x - bounding_rect.top_left_x;
|
||||
if (height)
|
||||
*height = bounding_rect.bottom_right_y - bounding_rect.top_left_y;
|
||||
}
|
||||
|
||||
if (center_x || center_y)
|
||||
{
|
||||
gdouble w, h;
|
||||
BoundingRectCoords bounding_rect = { DBL_MAX, DBL_MAX,
|
||||
DBL_MIN, DBL_MIN,
|
||||
TRUE };
|
||||
|
||||
g_hash_table_foreach (window->cur_touches,
|
||||
calculate_touch_bounding_rect,
|
||||
&bounding_rect);
|
||||
|
||||
w = bounding_rect.bottom_right_x - bounding_rect.top_left_x;
|
||||
h = bounding_rect.bottom_right_y - bounding_rect.top_left_y;
|
||||
|
||||
if (center_x)
|
||||
*center_x = bounding_rect.top_left_x + (w / 2);
|
||||
if (center_y)
|
||||
*center_y = bounding_rect.top_left_y + (h / 2);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_touch (MetaWindow *window,
|
||||
MetaDevice *source,
|
||||
guint touch_id,
|
||||
gboolean accept_events)
|
||||
{
|
||||
meta_error_trap_push_with_return (window->display);
|
||||
|
||||
XIAllowTouchEvents (window->display->xdisplay,
|
||||
meta_device_get_id (source),
|
||||
touch_id,
|
||||
(accept_events) ?
|
||||
XITouchOwnerAccept :
|
||||
XITouchOwnerRejectEnd);
|
||||
|
||||
if (meta_error_trap_pop_with_return (window->display) != Success)
|
||||
meta_warning ("XIAllowTouchEvents failed on touch sequence %d\n", touch_id);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_touch_events (MetaWindow *window,
|
||||
MetaDevice *source,
|
||||
gboolean accept_events)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, window->cur_touches);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
guint touch_id = GPOINTER_TO_UINT (key);
|
||||
MetaTouchInfo *info = value;
|
||||
|
||||
if (!info->notified)
|
||||
{
|
||||
notify_touch (window, source, touch_id, accept_events);
|
||||
info->notified = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_update_touch (MetaWindow *window,
|
||||
XEvent *event)
|
||||
{
|
||||
gdouble root_x, root_y;
|
||||
MetaTouchInfo *touch_info;
|
||||
gboolean new_touch = FALSE;
|
||||
MetaDevice *device, *source;
|
||||
guint touch_id, n_touches;
|
||||
Time evtime;
|
||||
|
||||
if (!window->cur_touches)
|
||||
window->cur_touches = g_hash_table_new (NULL, NULL);
|
||||
|
||||
meta_input_event_get_touch_id (window->display,
|
||||
event, &touch_id);
|
||||
|
||||
touch_info = g_hash_table_lookup (window->cur_touches,
|
||||
GUINT_TO_POINTER (touch_id));
|
||||
|
||||
meta_input_event_get_coordinates (window->display, event,
|
||||
NULL, NULL,
|
||||
&root_x, &root_y);
|
||||
|
||||
evtime = meta_input_event_get_time (window->display, event);
|
||||
device = meta_input_event_get_device (window->display, event);
|
||||
source = meta_input_event_get_source_device (window->display, event);
|
||||
|
||||
if (!touch_info)
|
||||
{
|
||||
touch_info = g_slice_new (MetaTouchInfo);
|
||||
touch_info->initial_root_x = root_x;
|
||||
touch_info->initial_root_y = root_y;
|
||||
touch_info->use_for_hotspot =
|
||||
(g_hash_table_size (window->cur_touches) < N_TOUCHES_FOR_GRAB);
|
||||
|
||||
g_hash_table_insert (window->cur_touches,
|
||||
GUINT_TO_POINTER (touch_id),
|
||||
touch_info);
|
||||
new_touch = TRUE;
|
||||
}
|
||||
|
||||
touch_info->root_x = root_x;
|
||||
touch_info->root_y = root_y;
|
||||
|
||||
n_touches = g_hash_table_size (window->cur_touches);
|
||||
|
||||
if (!new_touch && n_touches < N_TOUCHES_FOR_GRAB &&
|
||||
(ABS (touch_info->initial_root_x - touch_info->root_x) >= TOUCH_THRESHOLD ||
|
||||
ABS (touch_info->initial_root_y - touch_info->root_y) >= TOUCH_THRESHOLD))
|
||||
{
|
||||
/* There aren't yet enough touches on the window to trigger
|
||||
* window moving, and one of the touches moved past the
|
||||
* threshold, so the current touch sequences could actually
|
||||
* be meant for the client window, release all touches
|
||||
* altogether.
|
||||
*/
|
||||
notify_touch_events (window, source, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (n_touches >= N_TOUCHES_FOR_GRAB)
|
||||
{
|
||||
gdouble center_x, center_y, width, height;
|
||||
|
||||
if (n_touches == N_TOUCHES_FOR_GRAB && new_touch)
|
||||
{
|
||||
/* Accept all touches for the move operation */
|
||||
notify_touch_events (window, source, TRUE);
|
||||
}
|
||||
else if (!touch_info->notified)
|
||||
{
|
||||
/* All other touch sequences have been already
|
||||
* accepted, so only deal with the current one */
|
||||
notify_touch (window, source, touch_id, TRUE);
|
||||
touch_info->notified = TRUE;
|
||||
}
|
||||
|
||||
/* Set grab x/y coordinates at the middle of the bounding box,
|
||||
* this will be the hotspot for the window moving operation
|
||||
*/
|
||||
window_get_touch_area (window, ¢er_x, ¢er_y, &width, &height);
|
||||
window->cur_touch_area_width = width;
|
||||
window->cur_touch_area_height = height;
|
||||
|
||||
if (new_touch)
|
||||
{
|
||||
window->touch_hold_tiling_mode = FALSE;
|
||||
|
||||
/* (re)set initial bounding box
|
||||
* so the new touch is included
|
||||
*/
|
||||
window->initial_touch_area_width = width;
|
||||
window->initial_touch_area_height = height;
|
||||
|
||||
if (n_touches == N_TOUCHES_FOR_GRAB)
|
||||
{
|
||||
/* Start window move operation with the
|
||||
* bounding rectangle center as the hotspot
|
||||
*/
|
||||
meta_display_begin_grab_op (window->display,
|
||||
window->screen,
|
||||
window,
|
||||
device,
|
||||
META_GRAB_OP_MOVING,
|
||||
TRUE, FALSE,
|
||||
1, 0,
|
||||
evtime,
|
||||
center_x, center_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update hotspot for grab */
|
||||
window->cur_grab->grab_anchor_root_x = center_x;
|
||||
window->cur_grab->grab_anchor_root_y = center_y;
|
||||
window->cur_grab->grab_latest_motion_x = center_x;
|
||||
window->cur_grab->grab_latest_motion_y = center_y;
|
||||
meta_window_get_client_root_coords (window,
|
||||
&window->cur_grab->grab_anchor_window_pos);
|
||||
|
||||
/* Update window, and tiling mode */
|
||||
update_move (window, device, FALSE, center_x, center_y);
|
||||
}
|
||||
}
|
||||
else if (window->cur_grab)
|
||||
{
|
||||
/* Unset tiling mode as the remaining touches moved past the threshold */
|
||||
if (window->touch_hold_tiling_mode &&
|
||||
((window->cur_touch_area_width >
|
||||
(window->initial_touch_area_width + (2 * TOUCH_THRESHOLD))) ||
|
||||
(window->cur_touch_area_height >
|
||||
(window->initial_touch_area_height + (2 * TOUCH_THRESHOLD))) ||
|
||||
(ABS (window->cur_grab->grab_anchor_root_x -
|
||||
window->cur_grab->grab_latest_motion_x) > TOUCH_THRESHOLD) ||
|
||||
(ABS (window->cur_grab->grab_anchor_root_y -
|
||||
window->cur_grab->grab_latest_motion_y) > TOUCH_THRESHOLD)))
|
||||
window->touch_hold_tiling_mode = FALSE;
|
||||
|
||||
update_move (window, device, FALSE, center_x, center_y);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_end_touch (MetaWindow *window,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaTouchInfo *info;
|
||||
MetaDevice *source;
|
||||
guint touch_id, n_touches;
|
||||
MetaDevice *device;
|
||||
Time evtime;
|
||||
|
||||
meta_input_event_get_touch_id (window->display, event, &touch_id);
|
||||
evtime = meta_input_event_get_time (window->display, event);
|
||||
source = meta_input_event_get_source_device (window->display, event);
|
||||
|
||||
info = g_hash_table_lookup (window->cur_touches,
|
||||
GUINT_TO_POINTER (touch_id));
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (!info->notified)
|
||||
{
|
||||
notify_touch (window, source, touch_id, FALSE);
|
||||
info->notified = TRUE;
|
||||
}
|
||||
|
||||
g_hash_table_remove (window->cur_touches,
|
||||
GUINT_TO_POINTER (touch_id));
|
||||
|
||||
n_touches = g_hash_table_size (window->cur_touches);
|
||||
device = meta_input_event_get_device (window->display, event);
|
||||
|
||||
if (n_touches >= N_TOUCHES_FOR_GRAB)
|
||||
{
|
||||
gdouble center_x, center_y, width, height;
|
||||
|
||||
window_get_touch_area (window, ¢er_x, ¢er_y, &width, &height);
|
||||
|
||||
window->initial_touch_area_width = width;
|
||||
window->initial_touch_area_height = height;
|
||||
window->cur_touch_area_width = width;
|
||||
window->cur_touch_area_height = height;
|
||||
|
||||
/* Update hotspot to the new bounding box center */
|
||||
window->cur_grab->grab_anchor_root_x = center_x;
|
||||
window->cur_grab->grab_anchor_root_y = center_y;
|
||||
window->cur_grab->grab_latest_motion_x = center_x;
|
||||
window->cur_grab->grab_latest_motion_y = center_y;
|
||||
meta_window_get_client_root_coords (window,
|
||||
&window->cur_grab->grab_anchor_window_pos);
|
||||
|
||||
/* Hold tiling mode until the remaining
|
||||
* touches moved past some threshold
|
||||
*/
|
||||
window->touch_hold_tiling_mode = TRUE;
|
||||
|
||||
update_move (window, device, FALSE, center_x, center_y);
|
||||
}
|
||||
else if (n_touches == N_TOUCHES_FOR_GRAB - 1)
|
||||
{
|
||||
/* We just lost the last touch to hold the grab */
|
||||
window->initial_touch_area_width = 0;
|
||||
window->initial_touch_area_height = 0;
|
||||
window->cur_touch_area_width = 0;
|
||||
window->cur_touch_area_height = 0;
|
||||
|
||||
meta_display_end_grab_op (window->display, device, evtime);
|
||||
}
|
||||
else if (n_touches == 0 &&
|
||||
window->tile_mode != META_TILE_NONE)
|
||||
{
|
||||
meta_window_tile (window);
|
||||
update_tile_mode (window);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,6 +254,7 @@ typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
MetaDevice *device,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct _MetaKeyHandler MetaKeyHandler;
|
||||
|
||||
Reference in New Issue
Block a user