Compare commits
104 Commits
css-variab
...
touch-for-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a9ef1566d | ||
|
|
d22e419749 | ||
|
|
e5d6191466 | ||
|
|
eea2212445 | ||
|
|
bab5b76702 | ||
|
|
7fc2274025 | ||
|
|
0aced24ba5 | ||
|
|
a7f7d5e0cc | ||
|
|
a7914d68ea | ||
|
|
e50d1d1c4f | ||
|
|
11fae74750 | ||
|
|
9040388b18 | ||
|
|
35c9376791 | ||
|
|
3e9b4f9deb | ||
|
|
8d419898b7 | ||
|
|
aa9a8a9e75 | ||
|
|
0a641157ec | ||
|
|
7bd8d89694 | ||
|
|
7a1093a07d | ||
|
|
4556f13208 | ||
|
|
c2b7789ef5 | ||
|
|
4d01e5cb2d | ||
|
|
af0b3648ff | ||
|
|
6262ee58bb | ||
|
|
678027ed18 | ||
|
|
bd26f9ff77 | ||
|
|
97f65c9694 | ||
|
|
67245ed83e | ||
|
|
4becb95192 | ||
|
|
eed8b95744 | ||
|
|
adefcf2ee6 | ||
|
|
2adb94eed3 | ||
|
|
dfda82acd4 | ||
|
|
3e298f8605 | ||
|
|
5195cb807c | ||
|
|
cca0efbdf0 | ||
|
|
02fc18f34c | ||
|
|
59e14c5b56 | ||
|
|
acb93bd418 | ||
|
|
6ddf197e97 | ||
|
|
953f383d62 | ||
|
|
468e2957e7 | ||
|
|
064937ba1c | ||
|
|
bb4c1726ab | ||
|
|
4a26fcf212 | ||
|
|
9fc20c585d | ||
|
|
dda2ce7455 | ||
|
|
727200c6a0 | ||
|
|
b6f6ff901c | ||
|
|
0a535fe441 | ||
|
|
d3f8b132d6 | ||
|
|
b04f2cfb1c | ||
|
|
1e116569eb | ||
|
|
127c0c213d | ||
|
|
0cfd17eb77 | ||
|
|
30b3de7778 | ||
|
|
2044fb1a3b | ||
|
|
f09476686c | ||
|
|
123c0e0f3a | ||
|
|
31a79bd080 | ||
|
|
41be0fae6d | ||
|
|
d19998d2a5 | ||
|
|
89e53a0c61 | ||
|
|
b835349fa5 | ||
|
|
27b3dfb031 | ||
|
|
182b1afa18 | ||
|
|
48c70d1a1d | ||
|
|
910ca064e4 | ||
|
|
9775183efb | ||
|
|
605c7e161b | ||
|
|
f16fdbc6e4 | ||
|
|
2dc59d153c | ||
|
|
936d3df7c7 | ||
|
|
330a9bfbc3 | ||
|
|
59f7a3b5b4 | ||
|
|
bc1ee7bd0c | ||
|
|
5b32261d5a | ||
|
|
1d946085ec | ||
|
|
23b9e1257b | ||
|
|
e040c8840e | ||
|
|
909100ef0e | ||
|
|
b2b3154bb5 | ||
|
|
1e7d9fb60d | ||
|
|
b4f35b4183 | ||
|
|
bc5eacb185 | ||
|
|
523fd1fafa | ||
|
|
5e2cb82209 | ||
|
|
903fe8e892 | ||
|
|
c64fd529c1 | ||
|
|
1385eff197 | ||
|
|
177c20bc6e | ||
|
|
193341c85d | ||
|
|
7f03de11ef | ||
|
|
6cfadef0a7 | ||
|
|
7fb105e25e | ||
|
|
e5ff3129aa | ||
|
|
bf306a2424 | ||
|
|
f6600be559 | ||
|
|
66cb43da67 | ||
|
|
fcf2bd816c | ||
|
|
bef9f5c6c4 | ||
|
|
31cad1bb81 | ||
|
|
e0c442a4e8 | ||
|
|
b5469d783c |
@@ -935,7 +935,7 @@ if test "x$enable_x11_backend" = xyes; then
|
|||||||
have_base_x_pc=true
|
have_base_x_pc=true
|
||||||
X_PACKAGES="$X_PACKAGES x11 xext"
|
X_PACKAGES="$X_PACKAGES x11 xext"
|
||||||
x_libs="`$PKG_CONFIG --libs x11 xext`"
|
x_libs="`$PKG_CONFIG --libs x11 xext`"
|
||||||
X_CFLAGS="`$PKG_CONFIG --cflags x11 xext`"
|
X_CFLAGS="`$PKG_CONFIG --cflags x11 xext` -DXINPUT2_1_USE_UNSTABLE_PROTOCOL -DXINPUT2_2_USE_UNSTABLE_PROTOCOL"
|
||||||
|
|
||||||
# Strip out any .la files that pkg-config might give us (this happens
|
# Strip out any .la files that pkg-config might give us (this happens
|
||||||
# with -uninstalled.pc files)
|
# with -uninstalled.pc files)
|
||||||
@@ -1126,6 +1126,10 @@ if test "x$enable_x11_backend" = xyes; then
|
|||||||
AC_DEFINE(XINPUT_2, 1, [Define to 1 if XInput 2.0 is available]),
|
AC_DEFINE(XINPUT_2, 1, [Define to 1 if XInput 2.0 is available]),
|
||||||
X_EXTENSIONS="$X_EXTENSIONS XInput")
|
X_EXTENSIONS="$X_EXTENSIONS XInput")
|
||||||
|
|
||||||
|
gtk_save_LIBS="$LIBS"
|
||||||
|
LIBS="$LIBS -lXi"
|
||||||
|
AC_CHECK_FUNC(XIAllowTouchEvents, AC_DEFINE(XINPUT_2_2, 1, [Define to 1 if XInput 2.2 is available]))
|
||||||
|
LIBS="$gtk_save_LIBS"
|
||||||
else
|
else
|
||||||
AC_DEFINE(XINPUT_NONE, 1,
|
AC_DEFINE(XINPUT_NONE, 1,
|
||||||
[Define to 1 if no XInput should be used])
|
[Define to 1 if no XInput should be used])
|
||||||
|
|||||||
@@ -782,6 +782,8 @@ gdk_event_get_root_coords
|
|||||||
gdk_event_get_scroll_direction
|
gdk_event_get_scroll_direction
|
||||||
gdk_event_get_state
|
gdk_event_get_state
|
||||||
gdk_event_get_time
|
gdk_event_get_time
|
||||||
|
GdkEventSequence
|
||||||
|
gdk_event_get_event_sequence
|
||||||
gdk_event_request_motions
|
gdk_event_request_motions
|
||||||
gdk_events_get_angle
|
gdk_events_get_angle
|
||||||
gdk_events_get_center
|
gdk_events_get_center
|
||||||
@@ -819,6 +821,7 @@ GdkEvent
|
|||||||
GdkEventAny
|
GdkEventAny
|
||||||
GdkEventKey
|
GdkEventKey
|
||||||
GdkEventButton
|
GdkEventButton
|
||||||
|
GdkEventTouch
|
||||||
GdkEventScroll
|
GdkEventScroll
|
||||||
GdkEventMotion
|
GdkEventMotion
|
||||||
GdkEventExpose
|
GdkEventExpose
|
||||||
|
|||||||
@@ -2939,6 +2939,10 @@ gtk_scrolled_window_get_min_content_width
|
|||||||
gtk_scrolled_window_set_min_content_width
|
gtk_scrolled_window_set_min_content_width
|
||||||
gtk_scrolled_window_get_min_content_height
|
gtk_scrolled_window_get_min_content_height
|
||||||
gtk_scrolled_window_set_min_content_height
|
gtk_scrolled_window_set_min_content_height
|
||||||
|
gtk_scrolled_window_set_kinetic_scrolling
|
||||||
|
gtk_scrolled_window_get_kinetic_scrolling
|
||||||
|
gtk_scrolled_window_set_capture_button_press
|
||||||
|
gtk_scrolled_window_get_capture_button_press
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GTK_SCROLLED_WINDOW
|
GTK_SCROLLED_WINDOW
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ gdk_event_get_scroll_direction
|
|||||||
gdk_event_get_source_device
|
gdk_event_get_source_device
|
||||||
gdk_event_get_state
|
gdk_event_get_state
|
||||||
gdk_event_get_time
|
gdk_event_get_time
|
||||||
|
gdk_event_get_event_sequence
|
||||||
gdk_event_get_type
|
gdk_event_get_type
|
||||||
gdk_event_handler_set
|
gdk_event_handler_set
|
||||||
gdk_event_mask_get_type
|
gdk_event_mask_get_type
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ typedef enum
|
|||||||
* of a stylus on a graphics tablet.
|
* of a stylus on a graphics tablet.
|
||||||
* @GDK_SOURCE_CURSOR: the device is a graphics tablet "puck" or similar device.
|
* @GDK_SOURCE_CURSOR: the device is a graphics tablet "puck" or similar device.
|
||||||
* @GDK_SOURCE_KEYBOARD: the device is a keyboard.
|
* @GDK_SOURCE_KEYBOARD: the device is a keyboard.
|
||||||
|
* @GDK_SOURCE_TOUCHSCREEN: the device is a direct-input touch device, such
|
||||||
|
* as a touchscreen or tablet. This device type has been added in 3.4.
|
||||||
|
* @GDK_SOURCE_TOUCHPAD: the device is an indirect touch device, such
|
||||||
|
* as a touchpad. This device type has been added in 3.4.
|
||||||
*
|
*
|
||||||
* An enumeration describing the type of an input device in general terms.
|
* An enumeration describing the type of an input device in general terms.
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +74,9 @@ typedef enum
|
|||||||
GDK_SOURCE_PEN,
|
GDK_SOURCE_PEN,
|
||||||
GDK_SOURCE_ERASER,
|
GDK_SOURCE_ERASER,
|
||||||
GDK_SOURCE_CURSOR,
|
GDK_SOURCE_CURSOR,
|
||||||
GDK_SOURCE_KEYBOARD
|
GDK_SOURCE_KEYBOARD,
|
||||||
|
GDK_SOURCE_TOUCHSCREEN,
|
||||||
|
GDK_SOURCE_TOUCHPAD
|
||||||
} GdkInputSource;
|
} GdkInputSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
140
gdk/gdkdisplay.c
140
gdk/gdkdisplay.c
@@ -188,6 +188,7 @@ gdk_display_init (GdkDisplay *display)
|
|||||||
display->double_click_time = 250;
|
display->double_click_time = 250;
|
||||||
display->double_click_distance = 5;
|
display->double_click_distance = 5;
|
||||||
|
|
||||||
|
display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
|
||||||
display->device_grabs = g_hash_table_new (NULL, NULL);
|
display->device_grabs = g_hash_table_new (NULL, NULL);
|
||||||
display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
|
display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
(GDestroyNotify) g_free);
|
(GDestroyNotify) g_free);
|
||||||
@@ -236,6 +237,8 @@ gdk_display_finalize (GObject *object)
|
|||||||
NULL);
|
NULL);
|
||||||
g_hash_table_destroy (display->device_grabs);
|
g_hash_table_destroy (display->device_grabs);
|
||||||
|
|
||||||
|
g_array_free (display->touch_implicit_grabs, TRUE);
|
||||||
|
|
||||||
g_hash_table_destroy (display->motion_hint_info);
|
g_hash_table_destroy (display->motion_hint_info);
|
||||||
g_hash_table_destroy (display->pointers_info);
|
g_hash_table_destroy (display->pointers_info);
|
||||||
g_hash_table_destroy (display->multiple_click_info);
|
g_hash_table_destroy (display->multiple_click_info);
|
||||||
@@ -694,6 +697,75 @@ _gdk_display_add_device_grab (GdkDisplay *display,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gdk_display_break_touch_grabs (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkWindow *new_grab_window)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < display->touch_implicit_grabs->len; i++)
|
||||||
|
{
|
||||||
|
GdkTouchGrabInfo *info;
|
||||||
|
|
||||||
|
info = &g_array_index (display->touch_implicit_grabs,
|
||||||
|
GdkTouchGrabInfo, i);
|
||||||
|
|
||||||
|
if (info->device == device &&
|
||||||
|
info->window != new_grab_window)
|
||||||
|
generate_grab_broken_event (GDK_WINDOW (info->window),
|
||||||
|
device, TRUE, new_grab_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_display_add_touch_grab (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence,
|
||||||
|
GdkWindow *window,
|
||||||
|
GdkWindow *native_window,
|
||||||
|
GdkEventMask event_mask,
|
||||||
|
unsigned long serial,
|
||||||
|
guint32 time)
|
||||||
|
{
|
||||||
|
GdkTouchGrabInfo info;
|
||||||
|
|
||||||
|
info.device = device;
|
||||||
|
info.sequence = sequence;
|
||||||
|
info.window = g_object_ref (window);
|
||||||
|
info.native_window = g_object_ref (native_window);
|
||||||
|
info.serial = serial;
|
||||||
|
info.event_mask = event_mask;
|
||||||
|
info.time = time;
|
||||||
|
|
||||||
|
g_array_append_val (display->touch_implicit_grabs, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_gdk_display_end_touch_grab (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < display->touch_implicit_grabs->len; i++)
|
||||||
|
{
|
||||||
|
GdkTouchGrabInfo *info;
|
||||||
|
|
||||||
|
info = &g_array_index (display->touch_implicit_grabs,
|
||||||
|
GdkTouchGrabInfo, i);
|
||||||
|
|
||||||
|
if (info->device == device &&
|
||||||
|
info->sequence == sequence)
|
||||||
|
{
|
||||||
|
g_array_remove_index_fast (display->touch_implicit_grabs, i);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* _gdk_synthesize_crossing_events only works inside one toplevel.
|
/* _gdk_synthesize_crossing_events only works inside one toplevel.
|
||||||
This function splits things into two calls if needed, converting the
|
This function splits things into two calls if needed, converting the
|
||||||
coordinates to the right toplevel */
|
coordinates to the right toplevel */
|
||||||
@@ -897,15 +969,26 @@ switch_to_pointer_grab (GdkDisplay *display,
|
|||||||
|
|
||||||
if (grab == NULL) /* Ungrabbed, send events */
|
if (grab == NULL) /* Ungrabbed, send events */
|
||||||
{
|
{
|
||||||
pointer_window = NULL;
|
/* If the source device is a touch device, do not
|
||||||
if (new_toplevel)
|
* propagate any enter event yet, until one is
|
||||||
{
|
* synthesized when needed.
|
||||||
/* Find (possibly virtual) child window */
|
*/
|
||||||
pointer_window =
|
if (source_device &&
|
||||||
_gdk_window_find_descendant_at (new_toplevel,
|
(gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
|
||||||
x, y,
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD))
|
||||||
NULL, NULL);
|
info->need_touch_press_enter = TRUE;
|
||||||
}
|
|
||||||
|
pointer_window = NULL;
|
||||||
|
|
||||||
|
if (new_toplevel &&
|
||||||
|
!info->need_touch_press_enter)
|
||||||
|
{
|
||||||
|
/* Find (possibly virtual) child window */
|
||||||
|
pointer_window =
|
||||||
|
_gdk_window_find_descendant_at (new_toplevel,
|
||||||
|
x, y,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (pointer_window != last_grab->window)
|
if (pointer_window != last_grab->window)
|
||||||
synthesize_crossing_events (display, device, source_device,
|
synthesize_crossing_events (display, device, source_device,
|
||||||
@@ -964,12 +1047,15 @@ _gdk_display_device_grab_update (GdkDisplay *display,
|
|||||||
next_grab = NULL; /* Actually its not yet active */
|
next_grab = NULL; /* Actually its not yet active */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next_grab)
|
||||||
|
_gdk_display_break_touch_grabs (display, device, next_grab->window);
|
||||||
|
|
||||||
if ((next_grab == NULL && current_grab->implicit_ungrab) ||
|
if ((next_grab == NULL && current_grab->implicit_ungrab) ||
|
||||||
(next_grab != NULL && current_grab->window != next_grab->window))
|
(next_grab != NULL && current_grab->window != next_grab->window))
|
||||||
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
|
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
|
||||||
device,
|
device,
|
||||||
current_grab->implicit,
|
current_grab->implicit,
|
||||||
next_grab? next_grab->window : NULL);
|
next_grab? next_grab->window : NULL);
|
||||||
|
|
||||||
/* Remove old grab */
|
/* Remove old grab */
|
||||||
grabs = g_list_delete_link (grabs, grabs);
|
grabs = g_list_delete_link (grabs, grabs);
|
||||||
@@ -1028,6 +1114,34 @@ _gdk_display_has_device_grab (GdkDisplay *display,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GdkTouchGrabInfo *
|
||||||
|
_gdk_display_has_touch_grab (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence,
|
||||||
|
gulong serial)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < display->touch_implicit_grabs->len; i++)
|
||||||
|
{
|
||||||
|
GdkTouchGrabInfo *info;
|
||||||
|
|
||||||
|
info = &g_array_index (display->touch_implicit_grabs,
|
||||||
|
GdkTouchGrabInfo, i);
|
||||||
|
|
||||||
|
if (info->device == device &&
|
||||||
|
info->sequence == sequence)
|
||||||
|
{
|
||||||
|
if (serial >= info->serial)
|
||||||
|
return info;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns true if last grab was ended
|
/* Returns true if last grab was ended
|
||||||
* If if_child is non-NULL, end the grab only if the grabbed
|
* If if_child is non-NULL, end the grab only if the grabbed
|
||||||
* window is the same as if_child or a descendant of it */
|
* window is the same as if_child or a descendant of it */
|
||||||
|
|||||||
@@ -60,6 +60,19 @@ typedef struct
|
|||||||
guint implicit : 1;
|
guint implicit : 1;
|
||||||
} GdkDeviceGrabInfo;
|
} GdkDeviceGrabInfo;
|
||||||
|
|
||||||
|
/* Tracks information about a touch implicit grab on this display */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GdkDevice *device;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
|
||||||
|
GdkWindow *window;
|
||||||
|
GdkWindow *native_window;
|
||||||
|
gulong serial;
|
||||||
|
guint event_mask;
|
||||||
|
guint32 time;
|
||||||
|
} GdkTouchGrabInfo;
|
||||||
|
|
||||||
/* Tracks information about which window and position the pointer last was in.
|
/* Tracks information about which window and position the pointer last was in.
|
||||||
* This is useful when we need to synthesize events later.
|
* This is useful when we need to synthesize events later.
|
||||||
* Note that we track toplevel_under_pointer using enter/leave events,
|
* Note that we track toplevel_under_pointer using enter/leave events,
|
||||||
@@ -76,6 +89,7 @@ typedef struct
|
|||||||
guint32 state;
|
guint32 state;
|
||||||
guint32 button;
|
guint32 button;
|
||||||
GdkDevice *last_slave;
|
GdkDevice *last_slave;
|
||||||
|
guint need_touch_press_enter : 1;
|
||||||
} GdkPointerWindowInfo;
|
} GdkPointerWindowInfo;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -104,6 +118,7 @@ struct _GdkDisplay
|
|||||||
guint closed : 1; /* Whether this display has been closed */
|
guint closed : 1; /* Whether this display has been closed */
|
||||||
guint ignore_core_events : 1; /* Don't send core motion and button event */
|
guint ignore_core_events : 1; /* Don't send core motion and button event */
|
||||||
|
|
||||||
|
GArray *touch_implicit_grabs;
|
||||||
GHashTable *device_grabs;
|
GHashTable *device_grabs;
|
||||||
GHashTable *motion_hint_info;
|
GHashTable *motion_hint_info;
|
||||||
GdkDeviceManager *device_manager;
|
GdkDeviceManager *device_manager;
|
||||||
@@ -261,6 +276,21 @@ gboolean _gdk_display_end_device_grab (GdkDisplay *display
|
|||||||
gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
|
gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
|
||||||
GdkDevice *device,
|
GdkDevice *device,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
|
void _gdk_display_add_touch_grab (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence,
|
||||||
|
GdkWindow *window,
|
||||||
|
GdkWindow *native_window,
|
||||||
|
GdkEventMask event_mask,
|
||||||
|
unsigned long serial_start,
|
||||||
|
guint32 time);
|
||||||
|
GdkTouchGrabInfo * _gdk_display_has_touch_grab (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence,
|
||||||
|
gulong serial);
|
||||||
|
gboolean _gdk_display_end_touch_grab (GdkDisplay *display,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence);
|
||||||
void _gdk_display_enable_motion_hints (GdkDisplay *display,
|
void _gdk_display_enable_motion_hints (GdkDisplay *display,
|
||||||
GdkDevice *device);
|
GdkDevice *device);
|
||||||
GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,
|
GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,
|
||||||
|
|||||||
141
gdk/gdkevents.c
141
gdk/gdkevents.c
@@ -459,6 +459,15 @@ gdk_event_new (GdkEventType type)
|
|||||||
new_event->button.x_root = 0.;
|
new_event->button.x_root = 0.;
|
||||||
new_event->button.y_root = 0.;
|
new_event->button.y_root = 0.;
|
||||||
break;
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
new_event->touch.x = 0.;
|
||||||
|
new_event->touch.y = 0.;
|
||||||
|
new_event->touch.x_root = 0.;
|
||||||
|
new_event->touch.y_root = 0.;
|
||||||
|
break;
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
new_event->scroll.x = 0.;
|
new_event->scroll.x = 0.;
|
||||||
new_event->scroll.y = 0.;
|
new_event->scroll.y = 0.;
|
||||||
@@ -487,7 +496,31 @@ gdk_event_is_allocated (const GdkEvent *event)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_event_set_pointer_emulated (GdkEvent *event,
|
||||||
|
gboolean emulated)
|
||||||
|
{
|
||||||
|
if (gdk_event_is_allocated (event))
|
||||||
|
{
|
||||||
|
GdkEventPrivate *private = (GdkEventPrivate *) event;
|
||||||
|
|
||||||
|
if (emulated)
|
||||||
|
private->flags |= GDK_EVENT_POINTER_EMULATED;
|
||||||
|
else
|
||||||
|
private->flags &= ~(GDK_EVENT_POINTER_EMULATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_gdk_event_get_pointer_emulated (GdkEvent *event)
|
||||||
|
{
|
||||||
|
if (gdk_event_is_allocated (event))
|
||||||
|
return (((GdkEventPrivate *) event)->flags & GDK_EVENT_POINTER_EMULATED) != 0;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_event_copy:
|
* gdk_event_copy:
|
||||||
* @event: a #GdkEvent
|
* @event: a #GdkEvent
|
||||||
@@ -563,6 +596,15 @@ gdk_event_copy (const GdkEvent *event)
|
|||||||
sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
|
sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
if (event->touch.axes)
|
||||||
|
new_event->touch.axes = g_memdup (event->touch.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (event->touch.device));
|
||||||
|
break;
|
||||||
|
|
||||||
case GDK_MOTION_NOTIFY:
|
case GDK_MOTION_NOTIFY:
|
||||||
if (event->motion.axes)
|
if (event->motion.axes)
|
||||||
new_event->motion.axes = g_memdup (event->motion.axes,
|
new_event->motion.axes = g_memdup (event->motion.axes,
|
||||||
@@ -641,7 +683,14 @@ gdk_event_free (GdkEvent *event)
|
|||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
g_free (event->button.axes);
|
g_free (event->button.axes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
g_free (event->touch.axes);
|
||||||
|
break;
|
||||||
|
|
||||||
case GDK_EXPOSE:
|
case GDK_EXPOSE:
|
||||||
case GDK_DAMAGE:
|
case GDK_DAMAGE:
|
||||||
if (event->expose.region)
|
if (event->expose.region)
|
||||||
@@ -702,6 +751,11 @@ gdk_event_get_time (const GdkEvent *event)
|
|||||||
case GDK_3BUTTON_PRESS:
|
case GDK_3BUTTON_PRESS:
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
return event->button.time;
|
return event->button.time;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
return event->touch.time;
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
return event->scroll.time;
|
return event->scroll.time;
|
||||||
case GDK_KEY_PRESS:
|
case GDK_KEY_PRESS:
|
||||||
@@ -777,7 +831,13 @@ gdk_event_get_state (const GdkEvent *event,
|
|||||||
case GDK_2BUTTON_PRESS:
|
case GDK_2BUTTON_PRESS:
|
||||||
case GDK_3BUTTON_PRESS:
|
case GDK_3BUTTON_PRESS:
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
*state = event->button.state;
|
*state = event->button.state;
|
||||||
|
return TRUE;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
*state = event->touch.state;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
*state = event->scroll.state;
|
*state = event->scroll.state;
|
||||||
@@ -868,6 +928,13 @@ gdk_event_get_coords (const GdkEvent *event,
|
|||||||
x = event->button.x;
|
x = event->button.x;
|
||||||
y = event->button.y;
|
y = event->button.y;
|
||||||
break;
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
x = event->touch.x;
|
||||||
|
y = event->touch.y;
|
||||||
|
break;
|
||||||
case GDK_MOTION_NOTIFY:
|
case GDK_MOTION_NOTIFY:
|
||||||
x = event->motion.x;
|
x = event->motion.x;
|
||||||
y = event->motion.y;
|
y = event->motion.y;
|
||||||
@@ -922,6 +989,13 @@ gdk_event_get_root_coords (const GdkEvent *event,
|
|||||||
x = event->button.x_root;
|
x = event->button.x_root;
|
||||||
y = event->button.y_root;
|
y = event->button.y_root;
|
||||||
break;
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
x = event->touch.x_root;
|
||||||
|
y = event->touch.y_root;
|
||||||
|
break;
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
case GDK_LEAVE_NOTIFY:
|
case GDK_LEAVE_NOTIFY:
|
||||||
x = event->crossing.x_root;
|
x = event->crossing.x_root;
|
||||||
@@ -1162,7 +1236,7 @@ gdk_event_get_axis (const GdkEvent *event,
|
|||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case GDK_MOTION_NOTIFY:
|
case GDK_MOTION_NOTIFY:
|
||||||
x = event->motion.x;
|
x = event->motion.x;
|
||||||
y = event->motion.y;
|
y = event->motion.y;
|
||||||
break;
|
break;
|
||||||
@@ -1175,6 +1249,13 @@ gdk_event_get_axis (const GdkEvent *event,
|
|||||||
x = event->button.x;
|
x = event->button.x;
|
||||||
y = event->button.y;
|
y = event->button.y;
|
||||||
break;
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
x = event->touch.x;
|
||||||
|
y = event->touch.y;
|
||||||
|
break;
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
case GDK_LEAVE_NOTIFY:
|
case GDK_LEAVE_NOTIFY:
|
||||||
x = event->crossing.x;
|
x = event->crossing.x;
|
||||||
@@ -1198,6 +1279,14 @@ gdk_event_get_axis (const GdkEvent *event,
|
|||||||
device = event->button.device;
|
device = event->button.device;
|
||||||
axes = event->button.axes;
|
axes = event->button.axes;
|
||||||
}
|
}
|
||||||
|
else if (event->type == GDK_TOUCH_BEGIN ||
|
||||||
|
event->type == GDK_TOUCH_UPDATE ||
|
||||||
|
event->type == GDK_TOUCH_END ||
|
||||||
|
event->type == GDK_TOUCH_CANCEL)
|
||||||
|
{
|
||||||
|
device = event->touch.device;
|
||||||
|
axes = event->touch.axes;
|
||||||
|
}
|
||||||
else if (event->type == GDK_MOTION_NOTIFY)
|
else if (event->type == GDK_MOTION_NOTIFY)
|
||||||
{
|
{
|
||||||
device = event->motion.device;
|
device = event->motion.device;
|
||||||
@@ -1243,6 +1332,12 @@ gdk_event_set_device (GdkEvent *event,
|
|||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
event->button.device = device;
|
event->button.device = device;
|
||||||
break;
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
event->touch.device = device;
|
||||||
|
break;
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
event->scroll.device = device;
|
event->scroll.device = device;
|
||||||
break;
|
break;
|
||||||
@@ -1288,6 +1383,11 @@ gdk_event_get_device (const GdkEvent *event)
|
|||||||
case GDK_3BUTTON_PRESS:
|
case GDK_3BUTTON_PRESS:
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
return event->button.device;
|
return event->button.device;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
return event->touch.device;
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
return event->scroll.device;
|
return event->scroll.device;
|
||||||
case GDK_PROXIMITY_IN:
|
case GDK_PROXIMITY_IN:
|
||||||
@@ -1305,6 +1405,10 @@ gdk_event_get_device (const GdkEvent *event)
|
|||||||
case GDK_2BUTTON_PRESS:
|
case GDK_2BUTTON_PRESS:
|
||||||
case GDK_3BUTTON_PRESS:
|
case GDK_3BUTTON_PRESS:
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
case GDK_LEAVE_NOTIFY:
|
case GDK_LEAVE_NOTIFY:
|
||||||
case GDK_FOCUS_CHANGE:
|
case GDK_FOCUS_CHANGE:
|
||||||
@@ -1686,6 +1790,35 @@ gdk_event_get_screen (const GdkEvent *event)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_event_get_event_sequence:
|
||||||
|
* @event: a #GdkEvent
|
||||||
|
*
|
||||||
|
* Returns the #GdkEventSequence to which @event belongs.
|
||||||
|
* Currently, only touch events (i.e. those with type %GDK_TOUCH_BEGIN,
|
||||||
|
* %GDK_TOUCH_UPDATE, %GDK_TOUCH_END or %GDK_TOUCH_CANCEL) are
|
||||||
|
* connected in sequences. If the event does not belong to an
|
||||||
|
* event sequence, %NULL is returned.
|
||||||
|
*
|
||||||
|
* Returns: the event sequence that the event belongs to, or %NULL
|
||||||
|
*
|
||||||
|
* Since: 3.4
|
||||||
|
*/
|
||||||
|
GdkEventSequence *
|
||||||
|
gdk_event_get_event_sequence (const GdkEvent *event)
|
||||||
|
{
|
||||||
|
if (!event)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (event->type == GDK_TOUCH_BEGIN ||
|
||||||
|
event->type == GDK_TOUCH_UPDATE ||
|
||||||
|
event->type == GDK_TOUCH_END ||
|
||||||
|
event->type == GDK_TOUCH_CANCEL)
|
||||||
|
return event->touch.sequence;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_set_show_events:
|
* gdk_set_show_events:
|
||||||
* @show_events: %TRUE to output event debugging information.
|
* @show_events: %TRUE to output event debugging information.
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ typedef struct _GdkEventExpose GdkEventExpose;
|
|||||||
typedef struct _GdkEventVisibility GdkEventVisibility;
|
typedef struct _GdkEventVisibility GdkEventVisibility;
|
||||||
typedef struct _GdkEventMotion GdkEventMotion;
|
typedef struct _GdkEventMotion GdkEventMotion;
|
||||||
typedef struct _GdkEventButton GdkEventButton;
|
typedef struct _GdkEventButton GdkEventButton;
|
||||||
|
typedef struct _GdkEventTouch GdkEventTouch;
|
||||||
typedef struct _GdkEventScroll GdkEventScroll;
|
typedef struct _GdkEventScroll GdkEventScroll;
|
||||||
typedef struct _GdkEventKey GdkEventKey;
|
typedef struct _GdkEventKey GdkEventKey;
|
||||||
typedef struct _GdkEventFocus GdkEventFocus;
|
typedef struct _GdkEventFocus GdkEventFocus;
|
||||||
@@ -144,6 +145,8 @@ typedef struct _GdkEventWindowState GdkEventWindowState;
|
|||||||
typedef struct _GdkEventSetting GdkEventSetting;
|
typedef struct _GdkEventSetting GdkEventSetting;
|
||||||
typedef struct _GdkEventGrabBroken GdkEventGrabBroken;
|
typedef struct _GdkEventGrabBroken GdkEventGrabBroken;
|
||||||
|
|
||||||
|
typedef struct _GdkEventSequence GdkEventSequence;
|
||||||
|
|
||||||
typedef union _GdkEvent GdkEvent;
|
typedef union _GdkEvent GdkEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,6 +266,14 @@ typedef GdkFilterReturn (*GdkFilterFunc) (GdkXEvent *xevent,
|
|||||||
* was added in 2.8.
|
* was added in 2.8.
|
||||||
* @GDK_DAMAGE: the content of the window has been changed. This event type
|
* @GDK_DAMAGE: the content of the window has been changed. This event type
|
||||||
* was added in 2.14.
|
* was added in 2.14.
|
||||||
|
* @GDK_TOUCH_BEGIN: A new touch event sequence has just started. This event
|
||||||
|
* type was added in 3.4.
|
||||||
|
* @GDK_TOUCH_UPDATE: A touch event sequence has been updated. This event type
|
||||||
|
* was added in 3.4.
|
||||||
|
* @GDK_TOUCH_END: A touch event sequence has finished. This event type
|
||||||
|
* was added in 3.4.
|
||||||
|
* @GDK_TOUCH_CANCEL: A touch event sequence has been canceled. This event type
|
||||||
|
* was added in 3.4.
|
||||||
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration. Added in 2.18
|
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration. Added in 2.18
|
||||||
*
|
*
|
||||||
* Specifies the type of the event.
|
* Specifies the type of the event.
|
||||||
@@ -310,6 +321,10 @@ typedef enum
|
|||||||
GDK_OWNER_CHANGE = 34,
|
GDK_OWNER_CHANGE = 34,
|
||||||
GDK_GRAB_BROKEN = 35,
|
GDK_GRAB_BROKEN = 35,
|
||||||
GDK_DAMAGE = 36,
|
GDK_DAMAGE = 36,
|
||||||
|
GDK_TOUCH_BEGIN = 37,
|
||||||
|
GDK_TOUCH_UPDATE = 38,
|
||||||
|
GDK_TOUCH_END = 39,
|
||||||
|
GDK_TOUCH_CANCEL = 40,
|
||||||
GDK_EVENT_LAST /* helper variable for decls */
|
GDK_EVENT_LAST /* helper variable for decls */
|
||||||
} GdkEventType;
|
} GdkEventType;
|
||||||
|
|
||||||
@@ -385,6 +400,13 @@ typedef enum
|
|||||||
* @GDK_CROSSING_GTK_UNGRAB: crossing because a GTK+ grab is deactivated.
|
* @GDK_CROSSING_GTK_UNGRAB: crossing because a GTK+ grab is deactivated.
|
||||||
* @GDK_CROSSING_STATE_CHANGED: crossing because a GTK+ widget changed
|
* @GDK_CROSSING_STATE_CHANGED: crossing because a GTK+ widget changed
|
||||||
* state (e.g. sensitivity).
|
* state (e.g. sensitivity).
|
||||||
|
* @GDK_CROSSING_TOUCH_PRESS: crossing because a touch device was pressed,
|
||||||
|
* this event is synthetic as the pointer might have not left the window.
|
||||||
|
* @GDK_CROSSING_TOUCH_RELEASE: crossing because a touch device was released.
|
||||||
|
* this event is synthetic as the pointer might have not left the window.
|
||||||
|
* @GDK_CROSSING_DEVICE_SWITCH: crossing because of a device switch (i.e.
|
||||||
|
* a mouse taking control of the pointer after a touch device), this event
|
||||||
|
* is synthetic as the pointer didn't leave the window.
|
||||||
*
|
*
|
||||||
* Specifies the crossing mode for #GdkEventCrossing.
|
* Specifies the crossing mode for #GdkEventCrossing.
|
||||||
*/
|
*/
|
||||||
@@ -395,7 +417,10 @@ typedef enum
|
|||||||
GDK_CROSSING_UNGRAB,
|
GDK_CROSSING_UNGRAB,
|
||||||
GDK_CROSSING_GTK_GRAB,
|
GDK_CROSSING_GTK_GRAB,
|
||||||
GDK_CROSSING_GTK_UNGRAB,
|
GDK_CROSSING_GTK_UNGRAB,
|
||||||
GDK_CROSSING_STATE_CHANGED
|
GDK_CROSSING_STATE_CHANGED,
|
||||||
|
GDK_CROSSING_TOUCH_PRESS,
|
||||||
|
GDK_CROSSING_TOUCH_RELEASE,
|
||||||
|
GDK_CROSSING_DEVICE_SWITCH
|
||||||
} GdkCrossingMode;
|
} GdkCrossingMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,7 +598,7 @@ struct _GdkEventMotion
|
|||||||
/**
|
/**
|
||||||
* GdkEventButton:
|
* GdkEventButton:
|
||||||
* @type: the type of the event (%GDK_BUTTON_PRESS, %GDK_2BUTTON_PRESS,
|
* @type: the type of the event (%GDK_BUTTON_PRESS, %GDK_2BUTTON_PRESS,
|
||||||
* %GDK_3BUTTON_PRESS or %GDK_BUTTON_RELEASE).
|
* %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE).
|
||||||
* @window: the window which received the event.
|
* @window: the window which received the event.
|
||||||
* @send_event: %TRUE if the event was sent explicitly (e.g. using
|
* @send_event: %TRUE if the event was sent explicitly (e.g. using
|
||||||
* <function>XSendEvent</function>).
|
* <function>XSendEvent</function>).
|
||||||
@@ -597,7 +622,7 @@ struct _GdkEventMotion
|
|||||||
*
|
*
|
||||||
* Used for button press and button release events. The
|
* Used for button press and button release events. The
|
||||||
* @type field will be one of %GDK_BUTTON_PRESS,
|
* @type field will be one of %GDK_BUTTON_PRESS,
|
||||||
* %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, and %GDK_BUTTON_RELEASE.
|
* %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS or %GDK_BUTTON_RELEASE,
|
||||||
*
|
*
|
||||||
* Double and triple-clicks result in a sequence of events being received.
|
* Double and triple-clicks result in a sequence of events being received.
|
||||||
* For double-clicks the order of events will be:
|
* For double-clicks the order of events will be:
|
||||||
@@ -645,6 +670,57 @@ struct _GdkEventButton
|
|||||||
gdouble x_root, y_root;
|
gdouble x_root, y_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GdkEventTouch:
|
||||||
|
* @type: the type of the event (%GDK_TOUCH_BEGIN, %GDK_TOUCH_UPDATE,
|
||||||
|
* %GDK_TOUCH_END, %GDK_TOUCH_CANCEL)
|
||||||
|
* @window: the window which received the event
|
||||||
|
* @send_event: %TRUE if the event was sent explicitly (e.g. using
|
||||||
|
* <function>XSendEvent</function>)
|
||||||
|
* @time: the time of the event in milliseconds.
|
||||||
|
* @x: the x coordinate of the pointer relative to the window
|
||||||
|
* @y: the y coordinate of the pointer relative to the window
|
||||||
|
* @axes: @x, @y translated to the axes of @device, or %NULL if @device is
|
||||||
|
* the mouse
|
||||||
|
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||||
|
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||||
|
* buttons. See #GdkModifierType
|
||||||
|
* @sequence: the event sequence that the event belongs to
|
||||||
|
* @emulating_pointer: whether the event should be used for emulating
|
||||||
|
* pointer event
|
||||||
|
* @device: the device where the event originated
|
||||||
|
* @x_root: the x coordinate of the pointer relative to the root of the
|
||||||
|
* screen
|
||||||
|
* @y_root: the y coordinate of the pointer relative to the root of the
|
||||||
|
* screen
|
||||||
|
*
|
||||||
|
* Used for touch events.
|
||||||
|
* @type field will be one of %GDK_TOUCH_BEGIN, %GDK_TOUCH_UPDATE,
|
||||||
|
* %GDK_TOUCH_END or %GDK_TOUCH_CANCEL.
|
||||||
|
*
|
||||||
|
* Touch events are grouped into sequences by means of the @sequence
|
||||||
|
* field, which can also be obtained with gdk_event_get_event_sequence().
|
||||||
|
* Each sequence begins with a %GDK_TOUCH_BEGIN event, followed by
|
||||||
|
* any number of %GDK_TOUCH_UPDATE events, and ends with a %GDK_TOUCH_END
|
||||||
|
* (or %GDK_TOUCH_CANCEL) event. With multitouch devices, there may be
|
||||||
|
* several active sequences at the same time.
|
||||||
|
*/
|
||||||
|
struct _GdkEventTouch
|
||||||
|
{
|
||||||
|
GdkEventType type;
|
||||||
|
GdkWindow *window;
|
||||||
|
gint8 send_event;
|
||||||
|
guint32 time;
|
||||||
|
gdouble x;
|
||||||
|
gdouble y;
|
||||||
|
gdouble *axes;
|
||||||
|
guint state;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
gboolean emulating_pointer;
|
||||||
|
GdkDevice *device;
|
||||||
|
gdouble x_root, y_root;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GdkEventScroll:
|
* GdkEventScroll:
|
||||||
* @type: the type of the event (%GDK_SCROLL).
|
* @type: the type of the event (%GDK_SCROLL).
|
||||||
@@ -1073,6 +1149,7 @@ union _GdkEvent
|
|||||||
GdkEventVisibility visibility;
|
GdkEventVisibility visibility;
|
||||||
GdkEventMotion motion;
|
GdkEventMotion motion;
|
||||||
GdkEventButton button;
|
GdkEventButton button;
|
||||||
|
GdkEventTouch touch;
|
||||||
GdkEventScroll scroll;
|
GdkEventScroll scroll;
|
||||||
GdkEventKey key;
|
GdkEventKey key;
|
||||||
GdkEventCrossing crossing;
|
GdkEventCrossing crossing;
|
||||||
@@ -1150,6 +1227,8 @@ void gdk_event_set_screen (GdkEvent *event,
|
|||||||
GdkScreen *screen);
|
GdkScreen *screen);
|
||||||
GdkScreen *gdk_event_get_screen (const GdkEvent *event);
|
GdkScreen *gdk_event_get_screen (const GdkEvent *event);
|
||||||
|
|
||||||
|
GdkEventSequence *gdk_event_get_event_sequence (const GdkEvent *event);
|
||||||
|
|
||||||
void gdk_set_show_events (gboolean show_events);
|
void gdk_set_show_events (gboolean show_events);
|
||||||
gboolean gdk_get_show_events (void);
|
gboolean gdk_get_show_events (void);
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,13 @@ typedef enum
|
|||||||
/* Following flag is set for events on the event queue during
|
/* Following flag is set for events on the event queue during
|
||||||
* translation and cleared afterwards.
|
* translation and cleared afterwards.
|
||||||
*/
|
*/
|
||||||
GDK_EVENT_PENDING = 1 << 0
|
GDK_EVENT_PENDING = 1 << 0,
|
||||||
|
|
||||||
|
/* The following flag is set for:
|
||||||
|
* 1) touch events emulating pointer events
|
||||||
|
* 2) pointer events being emulated by a touch sequence.
|
||||||
|
*/
|
||||||
|
GDK_EVENT_POINTER_EMULATED = 1 << 1
|
||||||
} GdkEventFlags;
|
} GdkEventFlags;
|
||||||
|
|
||||||
struct _GdkEventPrivate
|
struct _GdkEventPrivate
|
||||||
@@ -275,6 +281,10 @@ GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
|
|||||||
void _gdk_event_filter_unref (GdkWindow *window,
|
void _gdk_event_filter_unref (GdkWindow *window,
|
||||||
GdkEventFilter *filter);
|
GdkEventFilter *filter);
|
||||||
|
|
||||||
|
void _gdk_event_set_pointer_emulated (GdkEvent *event,
|
||||||
|
gboolean emulated);
|
||||||
|
gboolean _gdk_event_get_pointer_emulated (GdkEvent *event);
|
||||||
|
|
||||||
void _gdk_event_emit (GdkEvent *event);
|
void _gdk_event_emit (GdkEvent *event);
|
||||||
GList* _gdk_event_queue_find_first (GdkDisplay *display);
|
GList* _gdk_event_queue_find_first (GdkDisplay *display);
|
||||||
void _gdk_event_queue_remove_link (GdkDisplay *display,
|
void _gdk_event_queue_remove_link (GdkDisplay *display,
|
||||||
@@ -318,6 +328,9 @@ gboolean _gdk_window_update_viewable (GdkWindow *window);
|
|||||||
|
|
||||||
void _gdk_window_process_updates_recurse (GdkWindow *window,
|
void _gdk_window_process_updates_recurse (GdkWindow *window,
|
||||||
cairo_region_t *expose_region);
|
cairo_region_t *expose_region);
|
||||||
|
gboolean _gdk_window_finish_touch_id (GdkWindow *window,
|
||||||
|
GdkDevice *device,
|
||||||
|
guint touch_id);
|
||||||
|
|
||||||
void _gdk_screen_close (GdkScreen *screen);
|
void _gdk_screen_close (GdkScreen *screen);
|
||||||
|
|
||||||
|
|||||||
@@ -350,6 +350,7 @@ typedef enum
|
|||||||
* @GDK_SUBSTRUCTURE_MASK: receive events about window configuration changes of
|
* @GDK_SUBSTRUCTURE_MASK: receive events about window configuration changes of
|
||||||
* child windows
|
* child windows
|
||||||
* @GDK_SCROLL_MASK: receive scroll events
|
* @GDK_SCROLL_MASK: receive scroll events
|
||||||
|
* @GDK_TOUCH_MASK: receive touch events
|
||||||
* @GDK_ALL_EVENTS_MASK: the combination of all the above event masks.
|
* @GDK_ALL_EVENTS_MASK: the combination of all the above event masks.
|
||||||
*
|
*
|
||||||
* A set of bit-flags to indicate which events a window is to receive.
|
* A set of bit-flags to indicate which events a window is to receive.
|
||||||
@@ -365,6 +366,13 @@ typedef enum
|
|||||||
* some of which are marked as a hint (the is_hint member is %TRUE).
|
* some of which are marked as a hint (the is_hint member is %TRUE).
|
||||||
* To receive more motion events after a motion hint event, the application
|
* To receive more motion events after a motion hint event, the application
|
||||||
* needs to asks for more, by calling gdk_event_request_motions().
|
* needs to asks for more, by calling gdk_event_request_motions().
|
||||||
|
*
|
||||||
|
* If %GDK_TOUCH_MASK is enabled, the window will receive touch events
|
||||||
|
* from touch-enabled devices. Those will come as sequences of #GdkEventTouch
|
||||||
|
* with type %GDK_TOUCH_UPDATE, enclosed by two events with
|
||||||
|
* type %GDK_TOUCH_BEGIN and %GDK_TOUCH_END (or %GDK_TOUCH_CANCEL).
|
||||||
|
* gdk_event_get_event_sequence() returns the event sequence for these
|
||||||
|
* events, so different sequences may be distinguished.
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -389,7 +397,8 @@ typedef enum
|
|||||||
GDK_PROXIMITY_OUT_MASK = 1 << 19,
|
GDK_PROXIMITY_OUT_MASK = 1 << 19,
|
||||||
GDK_SUBSTRUCTURE_MASK = 1 << 20,
|
GDK_SUBSTRUCTURE_MASK = 1 << 20,
|
||||||
GDK_SCROLL_MASK = 1 << 21,
|
GDK_SCROLL_MASK = 1 << 21,
|
||||||
GDK_ALL_EVENTS_MASK = 0x3FFFFE
|
GDK_TOUCH_MASK = 1 << 22,
|
||||||
|
GDK_ALL_EVENTS_MASK = 0x7FFFFE
|
||||||
} GdkEventMask;
|
} GdkEventMask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
492
gdk/gdkwindow.c
492
gdk/gdkwindow.c
@@ -1245,11 +1245,12 @@ get_native_device_event_mask (GdkWindow *private,
|
|||||||
* lists due to some non-native child window.
|
* lists due to some non-native child window.
|
||||||
*/
|
*/
|
||||||
if (gdk_window_is_toplevel (private) ||
|
if (gdk_window_is_toplevel (private) ||
|
||||||
mask & GDK_BUTTON_PRESS_MASK)
|
mask & GDK_BUTTON_PRESS_MASK)
|
||||||
mask |=
|
mask |=
|
||||||
GDK_POINTER_MOTION_MASK |
|
GDK_TOUCH_MASK |
|
||||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
GDK_POINTER_MOTION_MASK |
|
||||||
GDK_SCROLL_MASK;
|
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||||
|
GDK_SCROLL_MASK;
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
@@ -8119,6 +8120,10 @@ static const guint type_masks[] = {
|
|||||||
0, /* GDK_OWNER_CHANGE = 34 */
|
0, /* GDK_OWNER_CHANGE = 34 */
|
||||||
0, /* GDK_GRAB_BROKEN = 35 */
|
0, /* GDK_GRAB_BROKEN = 35 */
|
||||||
0, /* GDK_DAMAGE = 36 */
|
0, /* GDK_DAMAGE = 36 */
|
||||||
|
GDK_TOUCH_MASK, /* GDK_TOUCH_BEGIN = 37 */
|
||||||
|
GDK_TOUCH_MASK, /* GDK_TOUCH_UPDATE = 38 */
|
||||||
|
GDK_TOUCH_MASK, /* GDK_TOUCH_END = 39 */
|
||||||
|
GDK_TOUCH_MASK /* GDK_TOUCH_CANCEL = 40 */
|
||||||
};
|
};
|
||||||
G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
|
G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
|
||||||
|
|
||||||
@@ -8150,6 +8155,8 @@ is_button_type (GdkEventType type)
|
|||||||
type == GDK_2BUTTON_PRESS ||
|
type == GDK_2BUTTON_PRESS ||
|
||||||
type == GDK_3BUTTON_PRESS ||
|
type == GDK_3BUTTON_PRESS ||
|
||||||
type == GDK_BUTTON_RELEASE ||
|
type == GDK_BUTTON_RELEASE ||
|
||||||
|
type == GDK_TOUCH_BEGIN ||
|
||||||
|
type == GDK_TOUCH_END ||
|
||||||
type == GDK_SCROLL;
|
type == GDK_SCROLL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8157,10 +8164,20 @@ static gboolean
|
|||||||
is_motion_type (GdkEventType type)
|
is_motion_type (GdkEventType type)
|
||||||
{
|
{
|
||||||
return type == GDK_MOTION_NOTIFY ||
|
return type == GDK_MOTION_NOTIFY ||
|
||||||
|
type == GDK_TOUCH_UPDATE ||
|
||||||
type == GDK_ENTER_NOTIFY ||
|
type == GDK_ENTER_NOTIFY ||
|
||||||
type == GDK_LEAVE_NOTIFY;
|
type == GDK_LEAVE_NOTIFY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_touch_type (GdkEventType type)
|
||||||
|
{
|
||||||
|
return type == GDK_TOUCH_BEGIN ||
|
||||||
|
type == GDK_TOUCH_UPDATE ||
|
||||||
|
type == GDK_TOUCH_END ||
|
||||||
|
type == GDK_TOUCH_CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
static GdkWindow *
|
static GdkWindow *
|
||||||
find_common_ancestor (GdkWindow *win1,
|
find_common_ancestor (GdkWindow *win1,
|
||||||
GdkWindow *win2)
|
GdkWindow *win2)
|
||||||
@@ -8233,6 +8250,15 @@ _gdk_make_event (GdkWindow *window,
|
|||||||
event->button.state = the_state;
|
event->button.state = the_state;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
event->touch.time = the_time;
|
||||||
|
event->touch.axes = NULL;
|
||||||
|
event->touch.state = the_state;
|
||||||
|
break;
|
||||||
|
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
event->scroll.time = the_time;
|
event->scroll.time = the_time;
|
||||||
event->scroll.state = the_state;
|
event->scroll.state = the_state;
|
||||||
@@ -8321,12 +8347,27 @@ send_crossing_event (GdkDisplay *display,
|
|||||||
GdkEvent *event;
|
GdkEvent *event;
|
||||||
guint32 window_event_mask, type_event_mask;
|
guint32 window_event_mask, type_event_mask;
|
||||||
GdkDeviceGrabInfo *grab;
|
GdkDeviceGrabInfo *grab;
|
||||||
|
GdkTouchGrabInfo *touch_grab = NULL;
|
||||||
|
GdkPointerWindowInfo *pointer_info;
|
||||||
gboolean block_event = FALSE;
|
gboolean block_event = FALSE;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
|
||||||
grab = _gdk_display_has_device_grab (display, device, serial);
|
grab = _gdk_display_has_device_grab (display, device, serial);
|
||||||
|
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||||
|
|
||||||
if (grab != NULL &&
|
sequence = gdk_event_get_event_sequence (event_in_queue);
|
||||||
!grab->owner_events)
|
if (sequence)
|
||||||
|
touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
|
||||||
|
|
||||||
|
if (touch_grab)
|
||||||
|
{
|
||||||
|
if (window != touch_grab->window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window_event_mask = touch_grab->event_mask;
|
||||||
|
}
|
||||||
|
else if (grab != NULL &&
|
||||||
|
!grab->owner_events)
|
||||||
{
|
{
|
||||||
/* !owner_event => only report events wrt grab window, ignore rest */
|
/* !owner_event => only report events wrt grab window, ignore rest */
|
||||||
if ((GdkWindow *)window != grab->window)
|
if ((GdkWindow *)window != grab->window)
|
||||||
@@ -8336,7 +8377,14 @@ send_crossing_event (GdkDisplay *display,
|
|||||||
else
|
else
|
||||||
window_event_mask = window->event_mask;
|
window_event_mask = window->event_mask;
|
||||||
|
|
||||||
if (type == GDK_LEAVE_NOTIFY)
|
if (type == GDK_ENTER_NOTIFY &&
|
||||||
|
pointer_info->need_touch_press_enter &&
|
||||||
|
mode != GDK_CROSSING_TOUCH_PRESS &&
|
||||||
|
mode != GDK_CROSSING_TOUCH_RELEASE)
|
||||||
|
{
|
||||||
|
block_event = TRUE;
|
||||||
|
}
|
||||||
|
else if (type == GDK_LEAVE_NOTIFY)
|
||||||
{
|
{
|
||||||
type_event_mask = GDK_LEAVE_NOTIFY_MASK;
|
type_event_mask = GDK_LEAVE_NOTIFY_MASK;
|
||||||
window->devices_inside = g_list_remove (window->devices_inside, device);
|
window->devices_inside = g_list_remove (window->devices_inside, device);
|
||||||
@@ -9084,17 +9132,54 @@ _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
|
|||||||
static GdkWindow *
|
static GdkWindow *
|
||||||
get_event_window (GdkDisplay *display,
|
get_event_window (GdkDisplay *display,
|
||||||
GdkDevice *device,
|
GdkDevice *device,
|
||||||
GdkWindow *pointer_window,
|
GdkEventSequence *sequence,
|
||||||
GdkEventType type,
|
GdkWindow *pointer_window,
|
||||||
GdkModifierType mask,
|
GdkEventType type,
|
||||||
guint *evmask_out,
|
GdkModifierType mask,
|
||||||
gulong serial)
|
guint *evmask_out,
|
||||||
|
gboolean pointer_emulated,
|
||||||
|
gulong serial)
|
||||||
{
|
{
|
||||||
guint evmask;
|
guint evmask, emulated_mask = 0;
|
||||||
GdkWindow *grab_window;
|
GdkWindow *grab_window;
|
||||||
GdkDeviceGrabInfo *grab;
|
GdkDeviceGrabInfo *grab;
|
||||||
|
GdkTouchGrabInfo *touch_grab;
|
||||||
|
|
||||||
grab = _gdk_display_has_device_grab (display, device, serial);
|
touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
|
||||||
|
grab = _gdk_display_get_last_device_grab (display, device);
|
||||||
|
|
||||||
|
if (is_touch_type (type) && pointer_emulated)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
emulated_mask |= GDK_BUTTON_PRESS_MASK;
|
||||||
|
break;
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
emulated_mask |= GDK_BUTTON_MOTION_MASK;
|
||||||
|
break;
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
emulated_mask |= GDK_BUTTON_RELEASE_MASK;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touch_grab != NULL &&
|
||||||
|
(!grab || grab->implicit || touch_grab->serial >= grab->serial_start))
|
||||||
|
{
|
||||||
|
evmask = touch_grab->event_mask;
|
||||||
|
evmask = update_evmask_for_button_motion (evmask, mask);
|
||||||
|
|
||||||
|
if (evmask & (type_masks[type] | emulated_mask))
|
||||||
|
{
|
||||||
|
if (evmask_out)
|
||||||
|
*evmask_out = evmask;
|
||||||
|
return touch_grab->window;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (grab != NULL && !grab->owner_events)
|
if (grab != NULL && !grab->owner_events)
|
||||||
{
|
{
|
||||||
@@ -9103,7 +9188,7 @@ get_event_window (GdkDisplay *display,
|
|||||||
|
|
||||||
grab_window = grab->window;
|
grab_window = grab->window;
|
||||||
|
|
||||||
if (evmask & type_masks[type])
|
if (evmask & (type_masks[type] | emulated_mask))
|
||||||
{
|
{
|
||||||
if (evmask_out)
|
if (evmask_out)
|
||||||
*evmask_out = evmask;
|
*evmask_out = evmask;
|
||||||
@@ -9118,7 +9203,7 @@ get_event_window (GdkDisplay *display,
|
|||||||
evmask = pointer_window->event_mask;
|
evmask = pointer_window->event_mask;
|
||||||
evmask = update_evmask_for_button_motion (evmask, mask);
|
evmask = update_evmask_for_button_motion (evmask, mask);
|
||||||
|
|
||||||
if (evmask & type_masks[type])
|
if (evmask & (type_masks[type] | emulated_mask))
|
||||||
{
|
{
|
||||||
if (evmask_out)
|
if (evmask_out)
|
||||||
*evmask_out = evmask;
|
*evmask_out = evmask;
|
||||||
@@ -9134,7 +9219,7 @@ get_event_window (GdkDisplay *display,
|
|||||||
evmask = grab->event_mask;
|
evmask = grab->event_mask;
|
||||||
evmask = update_evmask_for_button_motion (evmask, mask);
|
evmask = update_evmask_for_button_motion (evmask, mask);
|
||||||
|
|
||||||
if (evmask & type_masks[type])
|
if (evmask & (type_masks[type] | emulated_mask))
|
||||||
{
|
{
|
||||||
if (evmask_out)
|
if (evmask_out)
|
||||||
*evmask_out = evmask;
|
*evmask_out = evmask;
|
||||||
@@ -9160,7 +9245,7 @@ proxy_pointer_event (GdkDisplay *display,
|
|||||||
guint state;
|
guint state;
|
||||||
gdouble toplevel_x, toplevel_y;
|
gdouble toplevel_x, toplevel_y;
|
||||||
guint32 time_;
|
guint32 time_;
|
||||||
gboolean non_linear;
|
gboolean non_linear, need_synthetic_enter = FALSE;
|
||||||
|
|
||||||
event_window = source_event->any.window;
|
event_window = source_event->any.window;
|
||||||
gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
|
gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
|
||||||
@@ -9180,6 +9265,16 @@ proxy_pointer_event (GdkDisplay *display,
|
|||||||
source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
|
source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
|
||||||
non_linear = TRUE;
|
non_linear = TRUE;
|
||||||
|
|
||||||
|
if (pointer_info->need_touch_press_enter &&
|
||||||
|
gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHSCREEN &&
|
||||||
|
gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHPAD &&
|
||||||
|
(source_event->type != GDK_TOUCH_UPDATE ||
|
||||||
|
_gdk_event_get_pointer_emulated (source_event)))
|
||||||
|
{
|
||||||
|
pointer_info->need_touch_press_enter = FALSE;
|
||||||
|
need_synthetic_enter = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we get crossing events with subwindow unexpectedly being NULL
|
/* If we get crossing events with subwindow unexpectedly being NULL
|
||||||
that means there is a native subwindow that gdk doesn't know about.
|
that means there is a native subwindow that gdk doesn't know about.
|
||||||
We track these and forward them, with the correct virtual window
|
We track these and forward them, with the correct virtual window
|
||||||
@@ -9267,7 +9362,9 @@ proxy_pointer_event (GdkDisplay *display,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pointer_info->window_under_pointer != pointer_window)
|
if ((source_event->type != GDK_TOUCH_UPDATE ||
|
||||||
|
_gdk_event_get_pointer_emulated (source_event)) &&
|
||||||
|
pointer_info->window_under_pointer != pointer_window)
|
||||||
{
|
{
|
||||||
/* Either a toplevel crossing notify that ended up inside a child window,
|
/* Either a toplevel crossing notify that ended up inside a child window,
|
||||||
or a motion notify that got into another child window */
|
or a motion notify that got into another child window */
|
||||||
@@ -9284,28 +9381,73 @@ proxy_pointer_event (GdkDisplay *display,
|
|||||||
serial, non_linear);
|
serial, non_linear);
|
||||||
_gdk_display_set_window_under_pointer (display, device, pointer_window);
|
_gdk_display_set_window_under_pointer (display, device, pointer_window);
|
||||||
}
|
}
|
||||||
else if (source_event->type == GDK_MOTION_NOTIFY)
|
else if (source_event->type == GDK_MOTION_NOTIFY ||
|
||||||
|
source_event->type == GDK_TOUCH_UPDATE)
|
||||||
{
|
{
|
||||||
GdkWindow *event_win;
|
GdkWindow *event_win;
|
||||||
guint evmask;
|
guint evmask;
|
||||||
gboolean is_hint;
|
gboolean is_hint;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
GdkEventType event_type;
|
||||||
|
|
||||||
|
sequence = gdk_event_get_event_sequence (source_event);
|
||||||
|
event_type = source_event->type;
|
||||||
|
|
||||||
event_win = get_event_window (display,
|
event_win = get_event_window (display,
|
||||||
device,
|
device,
|
||||||
|
sequence,
|
||||||
pointer_window,
|
pointer_window,
|
||||||
source_event->type,
|
source_event->type,
|
||||||
state,
|
state,
|
||||||
&evmask,
|
&evmask,
|
||||||
|
_gdk_event_get_pointer_emulated (source_event),
|
||||||
serial);
|
serial);
|
||||||
|
|
||||||
|
if (event_type == GDK_TOUCH_UPDATE)
|
||||||
|
{
|
||||||
|
if (_gdk_event_get_pointer_emulated (source_event))
|
||||||
|
{
|
||||||
|
/* Touch events emulating pointer events are transformed back
|
||||||
|
* to pointer events if:
|
||||||
|
* 1 - The event window doesn't select for touch events
|
||||||
|
* 2 - There's no touch grab for this sequence, which means
|
||||||
|
* it was started as a pointer sequence, but a device
|
||||||
|
* grab added touch events afterwards, the sequence must
|
||||||
|
* not mutate in this case.
|
||||||
|
*/
|
||||||
|
if ((evmask & GDK_TOUCH_MASK) == 0 ||
|
||||||
|
!_gdk_display_has_touch_grab (display, device, sequence, serial))
|
||||||
|
event_type = GDK_MOTION_NOTIFY;
|
||||||
|
}
|
||||||
|
else if ((evmask & GDK_TOUCH_MASK) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_touch_type (source_event->type) && !is_touch_type (event_type))
|
||||||
|
state |= GDK_BUTTON1_MASK;
|
||||||
|
|
||||||
if (event_win &&
|
if (event_win &&
|
||||||
gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
|
gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
|
||||||
gdk_window_get_device_events (event_win, device) == 0)
|
gdk_window_get_device_events (event_win, device) == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* The last device to interact with the window was a touch device,
|
||||||
|
* which synthesized a leave notify event, so synthesize another enter
|
||||||
|
* notify to tell the pointer is on the window.
|
||||||
|
*/
|
||||||
|
if (need_synthetic_enter)
|
||||||
|
_gdk_synthesize_crossing_events (display,
|
||||||
|
NULL, pointer_window,
|
||||||
|
device, source_device,
|
||||||
|
GDK_CROSSING_DEVICE_SWITCH,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
state, time_, NULL,
|
||||||
|
serial, FALSE);
|
||||||
|
|
||||||
is_hint = FALSE;
|
is_hint = FALSE;
|
||||||
|
|
||||||
if (event_win &&
|
if (event_win &&
|
||||||
|
event_type == GDK_MOTION_NOTIFY &&
|
||||||
(evmask & GDK_POINTER_MOTION_HINT_MASK))
|
(evmask & GDK_POINTER_MOTION_HINT_MASK))
|
||||||
{
|
{
|
||||||
gulong *device_serial;
|
gulong *device_serial;
|
||||||
@@ -9323,22 +9465,58 @@ proxy_pointer_event (GdkDisplay *display,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_win && !display->ignore_core_events)
|
if (!event_win)
|
||||||
{
|
return TRUE;
|
||||||
event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
|
|
||||||
event->motion.time = time_;
|
if (!display->ignore_core_events)
|
||||||
convert_toplevel_coords_to_window (event_win,
|
{
|
||||||
toplevel_x, toplevel_y,
|
event = gdk_event_new (event_type);
|
||||||
&event->motion.x, &event->motion.y);
|
event->any.window = g_object_ref (event_win);
|
||||||
event->motion.x_root = source_event->motion.x_root;
|
event->any.send_event = source_event->any.send_event;
|
||||||
event->motion.y_root = source_event->motion.y_root;
|
|
||||||
event->motion.state = state;
|
gdk_event_set_device (event, gdk_event_get_device (source_event));
|
||||||
event->motion.is_hint = is_hint;
|
|
||||||
event->motion.device = source_event->motion.device;
|
|
||||||
event->motion.axes = g_memdup (source_event->motion.axes,
|
|
||||||
sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
|
|
||||||
gdk_event_set_source_device (event, source_device);
|
gdk_event_set_source_device (event, source_device);
|
||||||
}
|
|
||||||
|
if (event_type == GDK_TOUCH_UPDATE)
|
||||||
|
{
|
||||||
|
event->touch.time = time_;
|
||||||
|
event->touch.state = state | GDK_BUTTON1_MASK;
|
||||||
|
event->touch.sequence = source_event->touch.sequence;
|
||||||
|
convert_toplevel_coords_to_window (event_win,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
&event->touch.x, &event->touch.y);
|
||||||
|
gdk_event_get_root_coords (source_event,
|
||||||
|
&event->touch.x_root,
|
||||||
|
&event->touch.y_root);
|
||||||
|
|
||||||
|
event->touch.axes = g_memdup (source_event->touch.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event->motion.time = time_;
|
||||||
|
event->motion.state = state;
|
||||||
|
event->motion.is_hint = is_hint;
|
||||||
|
|
||||||
|
convert_toplevel_coords_to_window (event_win,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
&event->motion.x, &event->motion.y);
|
||||||
|
gdk_event_get_root_coords (source_event,
|
||||||
|
&event->motion.x_root,
|
||||||
|
&event->motion.y_root);
|
||||||
|
|
||||||
|
if (is_touch_type (source_event->type))
|
||||||
|
event->motion.axes = g_memdup (source_event->touch.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
|
||||||
|
else
|
||||||
|
event->motion.axes = g_memdup (source_event->motion.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just insert the event */
|
||||||
|
_gdk_event_queue_insert_after (gdk_window_get_display (event_win),
|
||||||
|
source_event, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlink all move events from queue.
|
/* unlink all move events from queue.
|
||||||
@@ -9361,6 +9539,8 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
GdkWindow *pointer_window;
|
GdkWindow *pointer_window;
|
||||||
GdkWindow *parent;
|
GdkWindow *parent;
|
||||||
GdkEvent *event;
|
GdkEvent *event;
|
||||||
|
GdkPointerWindowInfo *pointer_info;
|
||||||
|
GdkDeviceGrabInfo *pointer_grab;
|
||||||
guint state;
|
guint state;
|
||||||
guint32 time_;
|
guint32 time_;
|
||||||
GdkEventType type;
|
GdkEventType type;
|
||||||
@@ -9368,6 +9548,8 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
GdkWindow *w;
|
GdkWindow *w;
|
||||||
GdkDevice *device, *source_device;
|
GdkDevice *device, *source_device;
|
||||||
|
GdkEventMask evmask;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
|
||||||
type = source_event->any.type;
|
type = source_event->any.type;
|
||||||
event_window = source_event->any.window;
|
event_window = source_event->any.window;
|
||||||
@@ -9381,9 +9563,17 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
toplevel_x, toplevel_y,
|
toplevel_x, toplevel_y,
|
||||||
&toplevel_x, &toplevel_y);
|
&toplevel_x, &toplevel_y);
|
||||||
|
|
||||||
if (type == GDK_BUTTON_PRESS &&
|
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||||
|
pointer_grab = _gdk_display_has_device_grab (display, device, serial);
|
||||||
|
|
||||||
|
sequence = gdk_event_get_event_sequence (source_event);
|
||||||
|
|
||||||
|
if ((type == GDK_BUTTON_PRESS ||
|
||||||
|
type == GDK_TOUCH_BEGIN) &&
|
||||||
!source_event->any.send_event &&
|
!source_event->any.send_event &&
|
||||||
_gdk_display_has_device_grab (display, device, serial) == NULL)
|
(!pointer_grab ||
|
||||||
|
(type == GDK_TOUCH_BEGIN && pointer_grab->implicit &&
|
||||||
|
!_gdk_event_get_pointer_emulated (source_event))))
|
||||||
{
|
{
|
||||||
pointer_window =
|
pointer_window =
|
||||||
_gdk_window_find_descendant_at (toplevel_window,
|
_gdk_window_find_descendant_at (toplevel_window,
|
||||||
@@ -9396,23 +9586,46 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
(parent = get_event_parent (w)) != NULL &&
|
(parent = get_event_parent (w)) != NULL &&
|
||||||
parent->window_type != GDK_WINDOW_ROOT)
|
parent->window_type != GDK_WINDOW_ROOT)
|
||||||
{
|
{
|
||||||
if (w->event_mask & GDK_BUTTON_PRESS_MASK)
|
if (w->event_mask & GDK_BUTTON_PRESS_MASK &&
|
||||||
|
(type == GDK_BUTTON_PRESS ||
|
||||||
|
_gdk_event_get_pointer_emulated (source_event)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (type == GDK_TOUCH_BEGIN &&
|
||||||
|
w->event_mask & GDK_TOUCH_MASK)
|
||||||
|
break;
|
||||||
|
|
||||||
w = parent;
|
w = parent;
|
||||||
}
|
}
|
||||||
pointer_window = (GdkWindow *)w;
|
pointer_window = w;
|
||||||
|
|
||||||
_gdk_display_add_device_grab (display,
|
if (pointer_window)
|
||||||
device,
|
{
|
||||||
pointer_window,
|
if (type == GDK_TOUCH_BEGIN &&
|
||||||
event_window,
|
pointer_window->event_mask & GDK_TOUCH_MASK)
|
||||||
GDK_OWNERSHIP_NONE,
|
{
|
||||||
FALSE,
|
_gdk_display_add_touch_grab (display, device, sequence,
|
||||||
gdk_window_get_events (pointer_window),
|
pointer_window, event_window,
|
||||||
serial,
|
gdk_window_get_events (pointer_window),
|
||||||
time_,
|
serial, time_);
|
||||||
TRUE);
|
}
|
||||||
_gdk_display_device_grab_update (display, device, source_device, serial);
|
else if (type == GDK_BUTTON_PRESS ||
|
||||||
|
_gdk_event_get_pointer_emulated (source_event))
|
||||||
|
{
|
||||||
|
_gdk_display_add_device_grab (display,
|
||||||
|
device,
|
||||||
|
pointer_window,
|
||||||
|
event_window,
|
||||||
|
GDK_OWNERSHIP_NONE,
|
||||||
|
FALSE,
|
||||||
|
gdk_window_get_events (pointer_window),
|
||||||
|
serial,
|
||||||
|
time_,
|
||||||
|
TRUE);
|
||||||
|
_gdk_display_device_grab_update (display, device,
|
||||||
|
source_device, serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer_window = get_pointer_window (display, toplevel_window, device,
|
pointer_window = get_pointer_window (display, toplevel_window, device,
|
||||||
@@ -9421,9 +9634,32 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
|
|
||||||
event_win = get_event_window (display,
|
event_win = get_event_window (display,
|
||||||
device,
|
device,
|
||||||
pointer_window,
|
sequence,
|
||||||
type, state,
|
pointer_window,
|
||||||
NULL, serial);
|
type, state,
|
||||||
|
&evmask,
|
||||||
|
_gdk_event_get_pointer_emulated (source_event),
|
||||||
|
serial);
|
||||||
|
|
||||||
|
if (type == GDK_TOUCH_BEGIN || type == GDK_TOUCH_END)
|
||||||
|
{
|
||||||
|
if (_gdk_event_get_pointer_emulated (source_event))
|
||||||
|
{
|
||||||
|
if ((evmask & GDK_TOUCH_MASK) == 0 ||
|
||||||
|
!_gdk_display_has_touch_grab (display, device, sequence, serial))
|
||||||
|
{
|
||||||
|
if (type == GDK_TOUCH_BEGIN)
|
||||||
|
type = GDK_BUTTON_PRESS;
|
||||||
|
else if (type == GDK_TOUCH_END)
|
||||||
|
type = GDK_BUTTON_RELEASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((evmask & GDK_TOUCH_MASK) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source_event->type == GDK_TOUCH_END && !is_touch_type (type))
|
||||||
|
state |= GDK_BUTTON1_MASK;
|
||||||
|
|
||||||
if (event_win == NULL || display->ignore_core_events)
|
if (event_win == NULL || display->ignore_core_events)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -9432,6 +9668,33 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
gdk_window_get_device_events (event_win, device) == 0)
|
gdk_window_get_device_events (event_win, device) == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
if ((type == GDK_BUTTON_PRESS ||
|
||||||
|
(type == GDK_TOUCH_BEGIN &&
|
||||||
|
_gdk_event_get_pointer_emulated (source_event))) &&
|
||||||
|
pointer_info->need_touch_press_enter)
|
||||||
|
{
|
||||||
|
GdkCrossingMode mode;
|
||||||
|
|
||||||
|
/* The last device to interact with the window was a touch device,
|
||||||
|
* which synthesized a leave notify event, so synthesize another enter
|
||||||
|
* notify to tell the pointer is on the window.
|
||||||
|
*/
|
||||||
|
if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
|
||||||
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD)
|
||||||
|
mode = GDK_CROSSING_TOUCH_PRESS;
|
||||||
|
else
|
||||||
|
mode = GDK_CROSSING_DEVICE_SWITCH;
|
||||||
|
|
||||||
|
pointer_info->need_touch_press_enter = FALSE;
|
||||||
|
_gdk_synthesize_crossing_events (display,
|
||||||
|
NULL,
|
||||||
|
pointer_info->window_under_pointer,
|
||||||
|
device, source_device, mode,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
state, time_, source_event,
|
||||||
|
serial, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
event = _gdk_make_event (event_win, type, source_event, FALSE);
|
event = _gdk_make_event (event_win, type, source_event, FALSE);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -9442,17 +9705,85 @@ proxy_button_event (GdkEvent *source_event,
|
|||||||
convert_toplevel_coords_to_window (event_win,
|
convert_toplevel_coords_to_window (event_win,
|
||||||
toplevel_x, toplevel_y,
|
toplevel_x, toplevel_y,
|
||||||
&event->button.x, &event->button.y);
|
&event->button.x, &event->button.y);
|
||||||
event->button.x_root = source_event->button.x_root;
|
gdk_event_get_root_coords (source_event,
|
||||||
event->button.y_root = source_event->button.y_root;
|
&event->button.x_root,
|
||||||
|
&event->button.y_root);
|
||||||
|
gdk_event_set_device (event, gdk_event_get_device (source_event));
|
||||||
|
gdk_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
event->button.state = state;
|
event->button.state = state;
|
||||||
event->button.device = source_event->button.device;
|
|
||||||
event->button.axes = g_memdup (source_event->button.axes,
|
if (type == GDK_BUTTON_RELEASE)
|
||||||
sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
|
event->button.state |= GDK_BUTTON1_MASK;
|
||||||
|
|
||||||
|
if (is_touch_type (source_event->type))
|
||||||
|
{
|
||||||
|
event->button.button = 1;
|
||||||
|
event->button.axes = g_memdup (source_event->touch.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event->button.button = source_event->button.button;
|
||||||
|
event->button.axes = g_memdup (source_event->button.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == GDK_BUTTON_PRESS)
|
||||||
|
_gdk_event_button_generate (display, event);
|
||||||
|
else if (type == GDK_BUTTON_RELEASE &&
|
||||||
|
pointer_window == pointer_info->window_under_pointer &&
|
||||||
|
(gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
|
||||||
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD))
|
||||||
|
{
|
||||||
|
/* Synthesize a leave notify event
|
||||||
|
* whenever a touch device is released
|
||||||
|
*/
|
||||||
|
pointer_info->need_touch_press_enter = TRUE;
|
||||||
|
_gdk_synthesize_crossing_events (display,
|
||||||
|
pointer_window, NULL,
|
||||||
|
device, source_device,
|
||||||
|
GDK_CROSSING_TOUCH_RELEASE,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
state, time_, NULL,
|
||||||
|
serial, FALSE);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
convert_toplevel_coords_to_window (event_win,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
&event->button.x, &event->button.y);
|
||||||
|
gdk_event_get_root_coords (source_event,
|
||||||
|
&event->touch.x_root,
|
||||||
|
&event->touch.y_root);
|
||||||
|
event->touch.state = state;
|
||||||
|
event->touch.device = source_event->touch.device;
|
||||||
|
event->touch.axes = g_memdup (source_event->touch.axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
|
||||||
|
event->touch.sequence = source_event->touch.sequence;
|
||||||
|
|
||||||
gdk_event_set_source_device (event, source_device);
|
gdk_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
if (type == GDK_BUTTON_PRESS)
|
if ((type == GDK_TOUCH_END &&
|
||||||
_gdk_event_button_generate (display, event);
|
_gdk_event_get_pointer_emulated (source_event)) &&
|
||||||
|
pointer_window == pointer_info->window_under_pointer &&
|
||||||
|
(gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
|
||||||
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD))
|
||||||
|
{
|
||||||
|
/* Synthesize a leave notify event
|
||||||
|
* whenever a touch device is released
|
||||||
|
*/
|
||||||
|
pointer_info->need_touch_press_enter = TRUE;
|
||||||
|
_gdk_synthesize_crossing_events (display,
|
||||||
|
pointer_window, NULL,
|
||||||
|
device, source_device,
|
||||||
|
GDK_CROSSING_TOUCH_RELEASE,
|
||||||
|
toplevel_x, toplevel_y,
|
||||||
|
state, time_, NULL,
|
||||||
|
serial, FALSE);
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
@@ -9682,7 +10013,9 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pointer_info)
|
if (pointer_info &&
|
||||||
|
(!is_touch_type (event->type) ||
|
||||||
|
_gdk_event_get_pointer_emulated (event)))
|
||||||
{
|
{
|
||||||
guint old_state, old_button;
|
guint old_state, old_button;
|
||||||
|
|
||||||
@@ -9699,6 +10032,9 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
|||||||
if (event->type == GDK_BUTTON_PRESS ||
|
if (event->type == GDK_BUTTON_PRESS ||
|
||||||
event->type == GDK_BUTTON_RELEASE)
|
event->type == GDK_BUTTON_RELEASE)
|
||||||
pointer_info->button = event->button.button;
|
pointer_info->button = event->button.button;
|
||||||
|
else if (event->type == GDK_TOUCH_BEGIN ||
|
||||||
|
event->type == GDK_TOUCH_END)
|
||||||
|
pointer_info->button = 1;
|
||||||
|
|
||||||
if (device &&
|
if (device &&
|
||||||
(pointer_info->state != old_state ||
|
(pointer_info->state != old_state ||
|
||||||
@@ -9712,16 +10048,32 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
|||||||
else if (is_button_type (event->type))
|
else if (is_button_type (event->type))
|
||||||
unlink_event = proxy_button_event (event, serial);
|
unlink_event = proxy_button_event (event, serial);
|
||||||
|
|
||||||
if (event->type == GDK_BUTTON_RELEASE && !event->any.send_event)
|
if ((event->type == GDK_BUTTON_RELEASE ||
|
||||||
|
event->type == GDK_TOUCH_END) &&
|
||||||
|
!event->any.send_event)
|
||||||
{
|
{
|
||||||
button_release_grab = _gdk_display_has_device_grab (display, device, serial);
|
GdkEventSequence *sequence;
|
||||||
if (button_release_grab &&
|
|
||||||
button_release_grab->implicit &&
|
sequence = gdk_event_get_event_sequence (event);
|
||||||
(event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
|
if (event->type == GDK_TOUCH_END && sequence)
|
||||||
{
|
{
|
||||||
button_release_grab->serial_end = serial;
|
_gdk_display_end_touch_grab (display, device, sequence);
|
||||||
button_release_grab->implicit_ungrab = FALSE;
|
}
|
||||||
_gdk_display_device_grab_update (display, device, source_device, serial);
|
|
||||||
|
if (event->type == GDK_BUTTON_RELEASE ||
|
||||||
|
_gdk_event_get_pointer_emulated (event))
|
||||||
|
{
|
||||||
|
button_release_grab =
|
||||||
|
_gdk_display_has_device_grab (display, device, serial);
|
||||||
|
|
||||||
|
if (button_release_grab &&
|
||||||
|
button_release_grab->implicit &&
|
||||||
|
(event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
|
||||||
|
{
|
||||||
|
button_release_grab->serial_end = serial;
|
||||||
|
button_release_grab->implicit_ungrab = FALSE;
|
||||||
|
_gdk_display_device_grab_update (display, device, source_device, serial);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ libgdkx11includedir = $(includedir)/gtk-3.0/gdk/x11
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-DG_LOG_DOMAIN=\"Gdk\" \
|
-DG_LOG_DOMAIN=\"Gdk\" \
|
||||||
-DGDK_COMPILATION \
|
-DGDK_COMPILATION \
|
||||||
|
-DXINPUT2_2_USE_UNSTABLE_PROTOCOL \
|
||||||
|
-DXINPUT2_1_USE_UNSTABLE_PROTOCOL \
|
||||||
-I$(top_srcdir) \
|
-I$(top_srcdir) \
|
||||||
-I$(top_srcdir)/gdk \
|
-I$(top_srcdir)/gdk \
|
||||||
-I$(top_builddir)/gdk \
|
-I$(top_builddir)/gdk \
|
||||||
|
|||||||
@@ -388,6 +388,7 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
|||||||
guint32 time_)
|
guint32 time_)
|
||||||
{
|
{
|
||||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||||
|
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
XIEventMask mask;
|
XIEventMask mask;
|
||||||
Window xwindow;
|
Window xwindow;
|
||||||
@@ -395,6 +396,7 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
|||||||
gint status;
|
gint status;
|
||||||
|
|
||||||
display = gdk_device_get_display (device);
|
display = gdk_device_get_display (device);
|
||||||
|
device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
|
||||||
|
|
||||||
/* FIXME: confine_to is actually unused */
|
/* FIXME: confine_to is actually unused */
|
||||||
|
|
||||||
@@ -409,7 +411,9 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mask.deviceid = device_xi2->device_id;
|
mask.deviceid = device_xi2->device_id;
|
||||||
mask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &mask.mask_len);
|
mask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
|
||||||
|
event_mask,
|
||||||
|
&mask.mask_len);
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
|
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
|
||||||
@@ -625,10 +629,17 @@ gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
|||||||
GdkEventMask event_mask)
|
GdkEventMask event_mask)
|
||||||
{
|
{
|
||||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||||
|
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||||
|
GdkDisplay *display;
|
||||||
XIEventMask evmask;
|
XIEventMask evmask;
|
||||||
|
|
||||||
|
display = gdk_device_get_display (device);
|
||||||
|
device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
|
||||||
|
|
||||||
evmask.deviceid = device_xi2->device_id;
|
evmask.deviceid = device_xi2->device_id;
|
||||||
evmask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &evmask.mask_len);
|
evmask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
|
||||||
|
event_mask,
|
||||||
|
&evmask.mask_len);
|
||||||
|
|
||||||
XISelectEvents (GDK_WINDOW_XDISPLAY (window),
|
XISelectEvents (GDK_WINDOW_XDISPLAY (window),
|
||||||
GDK_WINDOW_XID (window),
|
GDK_WINDOW_XID (window),
|
||||||
@@ -638,10 +649,14 @@ gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
guchar *
|
guchar *
|
||||||
_gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
_gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||||
gint *len)
|
GdkEventMask event_mask,
|
||||||
|
gint *len)
|
||||||
{
|
{
|
||||||
guchar *mask;
|
guchar *mask;
|
||||||
|
gint minor;
|
||||||
|
|
||||||
|
g_object_get (device_manager_xi2, "minor", &minor, NULL);
|
||||||
|
|
||||||
*len = XIMaskLen (XI_LASTEVENT);
|
*len = XIMaskLen (XI_LASTEVENT);
|
||||||
mask = g_new0 (guchar, *len);
|
mask = g_new0 (guchar, *len);
|
||||||
@@ -690,6 +705,17 @@ _gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
|||||||
XISetMask (mask, XI_FocusOut);
|
XISetMask (mask, XI_FocusOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef XINPUT_2_2
|
||||||
|
/* XInput 2.2 includes multitouch support */
|
||||||
|
if (minor >= 2 &&
|
||||||
|
event_mask & GDK_TOUCH_MASK)
|
||||||
|
{
|
||||||
|
XISetMask (mask, XI_TouchBegin);
|
||||||
|
XISetMask (mask, XI_TouchUpdate);
|
||||||
|
XISetMask (mask, XI_TouchEnd);
|
||||||
|
}
|
||||||
|
#endif /* XINPUT_2_2 */
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,11 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
|||||||
int major, minor;
|
int major, minor;
|
||||||
|
|
||||||
major = 2;
|
major = 2;
|
||||||
|
#ifdef XINPUT_2_2
|
||||||
|
minor = 2;
|
||||||
|
#else
|
||||||
minor = 0;
|
minor = 0;
|
||||||
|
#endif /* XINPUT_2_2 */
|
||||||
|
|
||||||
if (!_gdk_disable_multidevice &&
|
if (!_gdk_disable_multidevice &&
|
||||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||||
@@ -66,6 +70,8 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
|||||||
device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
|
device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
|
||||||
"display", display,
|
"display", display,
|
||||||
"opcode", opcode,
|
"opcode", opcode,
|
||||||
|
"major", major,
|
||||||
|
"minor", minor,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return GDK_DEVICE_MANAGER (device_manager_xi2);
|
return GDK_DEVICE_MANAGER (device_manager_xi2);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "gdkprivate-x11.h"
|
#include "gdkprivate-x11.h"
|
||||||
#include "gdkintl.h"
|
#include "gdkintl.h"
|
||||||
#include "gdkkeysyms.h"
|
#include "gdkkeysyms.h"
|
||||||
|
#include "gdkinternals.h"
|
||||||
|
|
||||||
#ifdef XINPUT_2
|
#ifdef XINPUT_2
|
||||||
|
|
||||||
@@ -49,6 +50,8 @@ struct _GdkX11DeviceManagerXI2
|
|||||||
GList *devices;
|
GList *devices;
|
||||||
|
|
||||||
gint opcode;
|
gint opcode;
|
||||||
|
gint major;
|
||||||
|
gint minor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkX11DeviceManagerXI2Class
|
struct _GdkX11DeviceManagerXI2Class
|
||||||
@@ -96,7 +99,9 @@ static GdkWindow * gdk_x11_device_manager_xi2_get_window (GdkEventTra
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_OPCODE
|
PROP_OPCODE,
|
||||||
|
PROP_MAJOR,
|
||||||
|
PROP_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -120,6 +125,20 @@ gdk_x11_device_manager_xi2_class_init (GdkX11DeviceManagerXI2Class *klass)
|
|||||||
P_("Opcode for XInput2 requests"),
|
P_("Opcode for XInput2 requests"),
|
||||||
0, G_MAXINT, 0,
|
0, G_MAXINT, 0,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_MAJOR,
|
||||||
|
g_param_spec_int ("major",
|
||||||
|
P_("Major"),
|
||||||
|
P_("Major version number"),
|
||||||
|
0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_MINOR,
|
||||||
|
g_param_spec_int ("minor",
|
||||||
|
P_("Minor"),
|
||||||
|
P_("Minor version number"),
|
||||||
|
0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -148,8 +167,10 @@ _gdk_x11_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
|
|||||||
static void
|
static void
|
||||||
translate_valuator_class (GdkDisplay *display,
|
translate_valuator_class (GdkDisplay *display,
|
||||||
GdkDevice *device,
|
GdkDevice *device,
|
||||||
XIValuatorClassInfo *info,
|
Atom valuator_label,
|
||||||
gint n_valuator)
|
gdouble min,
|
||||||
|
gdouble max,
|
||||||
|
gdouble resolution)
|
||||||
{
|
{
|
||||||
static gboolean initialized = FALSE;
|
static gboolean initialized = FALSE;
|
||||||
static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
|
static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
|
||||||
@@ -170,24 +191,19 @@ translate_valuator_class (GdkDisplay *display,
|
|||||||
|
|
||||||
for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
|
for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
|
||||||
{
|
{
|
||||||
if (label_atoms[i] == info->label)
|
if (label_atoms[i] == valuator_label)
|
||||||
{
|
{
|
||||||
use = i;
|
use = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->label != None)
|
if (valuator_label != None)
|
||||||
label = gdk_x11_xatom_to_atom_for_display (display, info->label);
|
label = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
|
||||||
else
|
else
|
||||||
label = GDK_NONE;
|
label = GDK_NONE;
|
||||||
|
|
||||||
_gdk_device_add_axis (device,
|
_gdk_device_add_axis (device, label, use, min, max, resolution);
|
||||||
label,
|
|
||||||
use,
|
|
||||||
info->min,
|
|
||||||
info->max,
|
|
||||||
info->resolution);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -196,7 +212,7 @@ translate_device_classes (GdkDisplay *display,
|
|||||||
XIAnyClassInfo **classes,
|
XIAnyClassInfo **classes,
|
||||||
guint n_classes)
|
guint n_classes)
|
||||||
{
|
{
|
||||||
gint i, n_valuator = 0;
|
gint i;
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (device));
|
g_object_freeze_notify (G_OBJECT (device));
|
||||||
|
|
||||||
@@ -218,10 +234,14 @@ translate_device_classes (GdkDisplay *display,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XIValuatorClass:
|
case XIValuatorClass:
|
||||||
translate_valuator_class (display, device,
|
{
|
||||||
(XIValuatorClassInfo *) class_info,
|
XIValuatorClassInfo *valuator_info = (XIValuatorClassInfo *) class_info;
|
||||||
n_valuator);
|
translate_valuator_class (display, device,
|
||||||
n_valuator++;
|
valuator_info->label,
|
||||||
|
valuator_info->min,
|
||||||
|
valuator_info->max,
|
||||||
|
valuator_info->resolution);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Ignore */
|
/* Ignore */
|
||||||
@@ -232,18 +252,58 @@ translate_device_classes (GdkDisplay *display,
|
|||||||
g_object_thaw_notify (G_OBJECT (device));
|
g_object_thaw_notify (G_OBJECT (device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_touch_device (XIAnyClassInfo **classes,
|
||||||
|
guint n_classes,
|
||||||
|
GdkInputSource *device_type,
|
||||||
|
gint *num_touches)
|
||||||
|
{
|
||||||
|
#ifdef XINPUT_2_2
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_classes; i++)
|
||||||
|
{
|
||||||
|
XITouchClassInfo *class = (XITouchClassInfo *) classes[i];
|
||||||
|
|
||||||
|
if (class->type != XITouchClass)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (class->num_touches > 0)
|
||||||
|
{
|
||||||
|
if (class->mode == XIDirectTouch)
|
||||||
|
*device_type = GDK_SOURCE_TOUCHSCREEN;
|
||||||
|
else if (class->mode == XIDependentTouch)
|
||||||
|
*device_type = GDK_SOURCE_TOUCHPAD;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*num_touches = class->num_touches;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static GdkDevice *
|
static GdkDevice *
|
||||||
create_device (GdkDeviceManager *device_manager,
|
create_device (GdkDeviceManager *device_manager,
|
||||||
GdkDisplay *display,
|
GdkDisplay *display,
|
||||||
XIDeviceInfo *dev)
|
XIDeviceInfo *dev)
|
||||||
{
|
{
|
||||||
GdkInputSource input_source;
|
GdkInputSource input_source;
|
||||||
|
GdkInputSource touch_source;
|
||||||
GdkDeviceType type;
|
GdkDeviceType type;
|
||||||
GdkDevice *device;
|
GdkDevice *device;
|
||||||
GdkInputMode mode;
|
GdkInputMode mode;
|
||||||
|
gint num_touches = 0;
|
||||||
|
|
||||||
if (dev->use == XIMasterKeyboard || dev->use == XISlaveKeyboard)
|
if (dev->use == XIMasterKeyboard || dev->use == XISlaveKeyboard)
|
||||||
input_source = GDK_SOURCE_KEYBOARD;
|
input_source = GDK_SOURCE_KEYBOARD;
|
||||||
|
else if (dev->use == XISlavePointer &&
|
||||||
|
is_touch_device (dev->classes, dev->num_classes, &touch_source, &num_touches))
|
||||||
|
input_source = touch_source;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gchar *tmp_name;
|
gchar *tmp_name;
|
||||||
@@ -254,6 +314,10 @@ create_device (GdkDeviceManager *device_manager,
|
|||||||
input_source = GDK_SOURCE_ERASER;
|
input_source = GDK_SOURCE_ERASER;
|
||||||
else if (strstr (tmp_name, "cursor"))
|
else if (strstr (tmp_name, "cursor"))
|
||||||
input_source = GDK_SOURCE_CURSOR;
|
input_source = GDK_SOURCE_CURSOR;
|
||||||
|
else if (strstr (tmp_name, "finger") ||
|
||||||
|
(strstr (tmp_name, "touch") &&
|
||||||
|
!strstr (tmp_name, "touchpad")))
|
||||||
|
input_source = GDK_SOURCE_TOUCHSCREEN;
|
||||||
else if (strstr (tmp_name, "wacom") ||
|
else if (strstr (tmp_name, "wacom") ||
|
||||||
strstr (tmp_name, "pen"))
|
strstr (tmp_name, "pen"))
|
||||||
input_source = GDK_SOURCE_PEN;
|
input_source = GDK_SOURCE_PEN;
|
||||||
@@ -282,6 +346,20 @@ create_device (GdkDeviceManager *device_manager,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDK_NOTE (INPUT,
|
||||||
|
({
|
||||||
|
const gchar *type_names[] = { "master", "slave", "floating" };
|
||||||
|
const gchar *source_names[] = { "mouse", "pen", "eraser", "cursor", "keyboard", "direct touch", "indirect touch" };
|
||||||
|
const gchar *mode_names[] = { "disabled", "screen", "window" };
|
||||||
|
g_message ("input device:\n\tname: %s\n\ttype: %s\n\tsource: %s\n\tmode: %s\n\thas cursor: %d\n\ttouches: %d",
|
||||||
|
dev->name,
|
||||||
|
type_names[type],
|
||||||
|
source_names[input_source],
|
||||||
|
mode_names[mode],
|
||||||
|
dev->use == XIMasterPointer,
|
||||||
|
num_touches);
|
||||||
|
}));
|
||||||
|
|
||||||
device = g_object_new (GDK_TYPE_X11_DEVICE_XI2,
|
device = g_object_new (GDK_TYPE_X11_DEVICE_XI2,
|
||||||
"name", dev->name,
|
"name", dev->name,
|
||||||
"type", type,
|
"type", type,
|
||||||
@@ -408,6 +486,8 @@ gdk_x11_device_manager_xi2_constructed (GObject *object)
|
|||||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
|
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
|
||||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||||
|
|
||||||
|
g_assert (device_manager->major == 2);
|
||||||
|
|
||||||
masters = g_hash_table_new (NULL, NULL);
|
masters = g_hash_table_new (NULL, NULL);
|
||||||
slaves = g_hash_table_new (NULL, NULL);
|
slaves = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
@@ -533,6 +613,12 @@ gdk_x11_device_manager_xi2_set_property (GObject *object,
|
|||||||
case PROP_OPCODE:
|
case PROP_OPCODE:
|
||||||
device_manager->opcode = g_value_get_int (value);
|
device_manager->opcode = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAJOR:
|
||||||
|
device_manager->major = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_MINOR:
|
||||||
|
device_manager->minor = g_value_get_int (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -554,6 +640,12 @@ gdk_x11_device_manager_xi2_get_property (GObject *object,
|
|||||||
case PROP_OPCODE:
|
case PROP_OPCODE:
|
||||||
g_value_set_int (value, device_manager->opcode);
|
g_value_set_int (value, device_manager->opcode);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAJOR:
|
||||||
|
g_value_set_int (value, device_manager->major);
|
||||||
|
break;
|
||||||
|
case PROP_MINOR:
|
||||||
|
g_value_set_int (value, device_manager->minor);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -823,6 +915,11 @@ get_event_window (GdkEventTranslator *translator,
|
|||||||
case XI_ButtonPress:
|
case XI_ButtonPress:
|
||||||
case XI_ButtonRelease:
|
case XI_ButtonRelease:
|
||||||
case XI_Motion:
|
case XI_Motion:
|
||||||
|
#ifdef XINPUT_2_2
|
||||||
|
case XI_TouchUpdate:
|
||||||
|
case XI_TouchBegin:
|
||||||
|
case XI_TouchEnd:
|
||||||
|
#endif /* XINPUT_2_2 */
|
||||||
{
|
{
|
||||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||||
|
|
||||||
@@ -1047,51 +1144,39 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
|||||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||||
GdkDevice *source_device;
|
GdkDevice *source_device;
|
||||||
|
|
||||||
switch (xev->detail)
|
if (ev->evtype == XI_ButtonPress &&
|
||||||
|
(xev->detail >= 4 && xev->detail <= 7))
|
||||||
{
|
{
|
||||||
case 4:
|
/* Button presses of button 4-7 are scroll events */
|
||||||
case 5:
|
event->scroll.type = GDK_SCROLL;
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
/* Button presses of button 4-7 are scroll events */
|
|
||||||
if (ev->evtype == XI_ButtonPress)
|
|
||||||
{
|
|
||||||
event->scroll.type = GDK_SCROLL;
|
|
||||||
|
|
||||||
if (xev->detail == 4)
|
if (xev->detail == 4)
|
||||||
event->scroll.direction = GDK_SCROLL_UP;
|
event->scroll.direction = GDK_SCROLL_UP;
|
||||||
else if (xev->detail == 5)
|
else if (xev->detail == 5)
|
||||||
event->scroll.direction = GDK_SCROLL_DOWN;
|
event->scroll.direction = GDK_SCROLL_DOWN;
|
||||||
else if (xev->detail == 6)
|
else if (xev->detail == 6)
|
||||||
event->scroll.direction = GDK_SCROLL_LEFT;
|
event->scroll.direction = GDK_SCROLL_LEFT;
|
||||||
else
|
else
|
||||||
event->scroll.direction = GDK_SCROLL_RIGHT;
|
event->scroll.direction = GDK_SCROLL_RIGHT;
|
||||||
|
|
||||||
event->scroll.window = window;
|
event->scroll.window = window;
|
||||||
event->scroll.time = xev->time;
|
event->scroll.time = xev->time;
|
||||||
event->scroll.x = (gdouble) xev->event_x;
|
event->scroll.x = (gdouble) xev->event_x;
|
||||||
event->scroll.y = (gdouble) xev->event_y;
|
event->scroll.y = (gdouble) xev->event_y;
|
||||||
event->scroll.x_root = (gdouble) xev->root_x;
|
event->scroll.x_root = (gdouble) xev->root_x;
|
||||||
event->scroll.y_root = (gdouble) xev->root_y;
|
event->scroll.y_root = (gdouble) xev->root_y;
|
||||||
|
|
||||||
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
|
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
|
||||||
GUINT_TO_POINTER (xev->deviceid));
|
GUINT_TO_POINTER (xev->deviceid));
|
||||||
|
|
||||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||||
GUINT_TO_POINTER (xev->sourceid));
|
GUINT_TO_POINTER (xev->sourceid));
|
||||||
gdk_event_set_source_device (event, source_device);
|
gdk_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||||
break;
|
}
|
||||||
}
|
else
|
||||||
/* Button presses of button 4-7 are scroll events, so ignore the release */
|
{
|
||||||
else if (ev->evtype == XI_ButtonRelease)
|
|
||||||
{
|
|
||||||
return_val = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* else (XI_ButtonRelease) fall thru */
|
|
||||||
default:
|
|
||||||
event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
|
event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
|
||||||
|
|
||||||
event->button.window = window;
|
event->button.window = window;
|
||||||
@@ -1124,9 +1209,13 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
event->button.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
event->button.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||||
|
|
||||||
event->button.button = xev->detail;
|
event->button.button = xev->detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xev->flags & XIPointerEmulated)
|
||||||
|
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||||
|
|
||||||
if (return_val == FALSE)
|
if (return_val == FALSE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1141,15 +1230,14 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case XI_Motion:
|
case XI_Motion:
|
||||||
{
|
{
|
||||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||||
GdkDevice *source_device;
|
GdkDevice *source_device;
|
||||||
|
|
||||||
event->motion.type = GDK_MOTION_NOTIFY;
|
event->motion.type = GDK_MOTION_NOTIFY;
|
||||||
|
|
||||||
event->motion.window = window;
|
event->motion.window = window;
|
||||||
|
|
||||||
event->motion.time = xev->time;
|
event->motion.time = xev->time;
|
||||||
event->motion.x = (gdouble) xev->event_x;
|
event->motion.x = (gdouble) xev->event_x;
|
||||||
event->motion.y = (gdouble) xev->event_y;
|
event->motion.y = (gdouble) xev->event_y;
|
||||||
@@ -1165,6 +1253,9 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
|||||||
|
|
||||||
event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||||
|
|
||||||
|
if (xev->flags & XIPointerEmulated)
|
||||||
|
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||||
|
|
||||||
/* There doesn't seem to be motion hints in XI */
|
/* There doesn't seem to be motion hints in XI */
|
||||||
event->motion.is_hint = FALSE;
|
event->motion.is_hint = FALSE;
|
||||||
|
|
||||||
@@ -1184,6 +1275,137 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef XINPUT_2_2
|
||||||
|
case XI_TouchBegin:
|
||||||
|
case XI_TouchEnd:
|
||||||
|
{
|
||||||
|
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||||
|
GdkDevice *source_device;
|
||||||
|
|
||||||
|
GDK_NOTE(EVENTS,
|
||||||
|
g_message ("touch %s:\twindow %ld\n\ttouch id: %u\n\tpointer emulating: %d",
|
||||||
|
ev->evtype == XI_TouchBegin ? "begin" : "end",
|
||||||
|
xev->event,
|
||||||
|
xev->detail,
|
||||||
|
xev->flags & XITouchEmulatingPointer));
|
||||||
|
|
||||||
|
if (ev->evtype == XI_TouchBegin)
|
||||||
|
event->touch.type = GDK_TOUCH_BEGIN;
|
||||||
|
else if (ev->evtype == XI_TouchEnd)
|
||||||
|
event->touch.type = GDK_TOUCH_END;
|
||||||
|
|
||||||
|
event->touch.window = window;
|
||||||
|
event->touch.time = xev->time;
|
||||||
|
event->touch.x = (gdouble) xev->event_x;
|
||||||
|
event->touch.y = (gdouble) xev->event_y;
|
||||||
|
event->touch.x_root = (gdouble) xev->root_x;
|
||||||
|
event->touch.y_root = (gdouble) xev->root_y;
|
||||||
|
|
||||||
|
event->touch.device = g_hash_table_lookup (device_manager->id_table,
|
||||||
|
GUINT_TO_POINTER (xev->deviceid));
|
||||||
|
|
||||||
|
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||||
|
GUINT_TO_POINTER (xev->sourceid));
|
||||||
|
gdk_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
|
event->touch.axes = translate_axes (event->touch.device,
|
||||||
|
event->touch.x,
|
||||||
|
event->touch.y,
|
||||||
|
event->touch.window,
|
||||||
|
&xev->valuators);
|
||||||
|
|
||||||
|
if (gdk_device_get_mode (event->touch.device) == GDK_MODE_WINDOW)
|
||||||
|
{
|
||||||
|
GdkDevice *device = event->touch.device;
|
||||||
|
|
||||||
|
/* Update event coordinates from axes */
|
||||||
|
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_X, &event->touch.x);
|
||||||
|
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||||
|
|
||||||
|
if (ev->evtype == XI_TouchBegin)
|
||||||
|
event->touch.state |= GDK_BUTTON1_MASK;
|
||||||
|
|
||||||
|
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||||
|
|
||||||
|
if (xev->flags & XITouchEmulatingPointer)
|
||||||
|
{
|
||||||
|
event->touch.emulating_pointer = TRUE;
|
||||||
|
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (return_val == FALSE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!set_screen_from_root (display, event, xev->root))
|
||||||
|
{
|
||||||
|
return_val = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev->evtype == XI_TouchBegin)
|
||||||
|
set_user_time (event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XI_TouchUpdate:
|
||||||
|
{
|
||||||
|
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||||
|
GdkDevice *source_device;
|
||||||
|
|
||||||
|
GDK_NOTE(EVENTS,
|
||||||
|
g_message ("touch update:\twindow %ld\n\ttouch id: %u\n\tpointer emulating: %d",
|
||||||
|
xev->event,
|
||||||
|
xev->detail,
|
||||||
|
xev->flags & XITouchEmulatingPointer));
|
||||||
|
|
||||||
|
event->touch.window = window;
|
||||||
|
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||||
|
event->touch.type = GDK_TOUCH_UPDATE;
|
||||||
|
event->touch.time = xev->time;
|
||||||
|
event->touch.x = (gdouble) xev->event_x;
|
||||||
|
event->touch.y = (gdouble) xev->event_y;
|
||||||
|
event->touch.x_root = (gdouble) xev->root_x;
|
||||||
|
event->touch.y_root = (gdouble) xev->root_y;
|
||||||
|
|
||||||
|
event->touch.device = g_hash_table_lookup (device_manager->id_table,
|
||||||
|
GINT_TO_POINTER (xev->deviceid));
|
||||||
|
|
||||||
|
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||||
|
GUINT_TO_POINTER (xev->sourceid));
|
||||||
|
gdk_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
|
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||||
|
|
||||||
|
event->touch.state |= GDK_BUTTON1_MASK;
|
||||||
|
|
||||||
|
if (xev->flags & XITouchEmulatingPointer)
|
||||||
|
{
|
||||||
|
event->touch.emulating_pointer = TRUE;
|
||||||
|
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
event->touch.axes = translate_axes (event->touch.device,
|
||||||
|
event->touch.x,
|
||||||
|
event->touch.y,
|
||||||
|
event->touch.window,
|
||||||
|
&xev->valuators);
|
||||||
|
|
||||||
|
if (gdk_device_get_mode (event->touch.device) == GDK_MODE_WINDOW)
|
||||||
|
{
|
||||||
|
GdkDevice *device = event->touch.device;
|
||||||
|
|
||||||
|
/* Update event coordinates from axes */
|
||||||
|
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_X, &event->touch.x);
|
||||||
|
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case XI_Enter:
|
case XI_Enter:
|
||||||
case XI_Leave:
|
case XI_Leave:
|
||||||
{
|
{
|
||||||
@@ -1280,7 +1502,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
|
|||||||
GDK_BUTTON2_MOTION_MASK |
|
GDK_BUTTON2_MOTION_MASK |
|
||||||
GDK_BUTTON3_MOTION_MASK |
|
GDK_BUTTON3_MOTION_MASK |
|
||||||
GDK_BUTTON_MOTION_MASK |
|
GDK_BUTTON_MOTION_MASK |
|
||||||
GDK_FOCUS_CHANGE_MASK);
|
GDK_FOCUS_CHANGE_MASK |
|
||||||
|
GDK_TOUCH_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1294,7 +1517,9 @@ gdk_x11_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
|
|||||||
device_manager = GDK_DEVICE_MANAGER (translator);
|
device_manager = GDK_DEVICE_MANAGER (translator);
|
||||||
|
|
||||||
event_mask.deviceid = XIAllMasterDevices;
|
event_mask.deviceid = XIAllMasterDevices;
|
||||||
event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (evmask, &event_mask.mask_len);
|
event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
|
||||||
|
evmask,
|
||||||
|
&event_mask.mask_len);
|
||||||
|
|
||||||
_gdk_x11_device_manager_xi2_select_events (device_manager, window, &event_mask);
|
_gdk_x11_device_manager_xi2_select_events (device_manager, window, &event_mask);
|
||||||
g_free (event_mask.mask);
|
g_free (event_mask.mask);
|
||||||
|
|||||||
@@ -247,8 +247,9 @@ void _gdk_x11_device_xi_translate_axes (GdkDevice *device,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XINPUT_2
|
#ifdef XINPUT_2
|
||||||
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||||
gint *len);
|
GdkEventMask event_mask,
|
||||||
|
gint *len);
|
||||||
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||||
XIButtonState *buttons_state,
|
XIButtonState *buttons_state,
|
||||||
XIGroupState *group_state);
|
XIGroupState *group_state);
|
||||||
|
|||||||
@@ -2367,6 +2367,8 @@ gtk_scrollbar_new
|
|||||||
gtk_scrolled_window_add_with_viewport
|
gtk_scrolled_window_add_with_viewport
|
||||||
gtk_scrolled_window_get_hadjustment
|
gtk_scrolled_window_get_hadjustment
|
||||||
gtk_scrolled_window_get_hscrollbar
|
gtk_scrolled_window_get_hscrollbar
|
||||||
|
gtk_scrolled_window_get_kinetic_scrolling
|
||||||
|
gtk_scrolled_window_get_capture_button_press
|
||||||
gtk_scrolled_window_get_min_content_height
|
gtk_scrolled_window_get_min_content_height
|
||||||
gtk_scrolled_window_get_min_content_width
|
gtk_scrolled_window_get_min_content_width
|
||||||
gtk_scrolled_window_get_placement
|
gtk_scrolled_window_get_placement
|
||||||
@@ -2377,6 +2379,8 @@ gtk_scrolled_window_get_vadjustment
|
|||||||
gtk_scrolled_window_get_vscrollbar
|
gtk_scrolled_window_get_vscrollbar
|
||||||
gtk_scrolled_window_new
|
gtk_scrolled_window_new
|
||||||
gtk_scrolled_window_set_hadjustment
|
gtk_scrolled_window_set_hadjustment
|
||||||
|
gtk_scrolled_window_set_kinetic_scrolling
|
||||||
|
gtk_scrolled_window_set_capture_button_press
|
||||||
gtk_scrolled_window_set_min_content_height
|
gtk_scrolled_window_set_min_content_height
|
||||||
gtk_scrolled_window_set_min_content_width
|
gtk_scrolled_window_set_min_content_width
|
||||||
gtk_scrolled_window_set_placement
|
gtk_scrolled_window_set_placement
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ static gint gtk_button_button_press (GtkWidget * widget,
|
|||||||
GdkEventButton * event);
|
GdkEventButton * event);
|
||||||
static gint gtk_button_button_release (GtkWidget * widget,
|
static gint gtk_button_button_release (GtkWidget * widget,
|
||||||
GdkEventButton * event);
|
GdkEventButton * event);
|
||||||
|
static gboolean gtk_button_touch (GtkWidget *widget,
|
||||||
|
GdkEventTouch *event);
|
||||||
static gint gtk_button_grab_broken (GtkWidget * widget,
|
static gint gtk_button_grab_broken (GtkWidget * widget,
|
||||||
GdkEventGrabBroken * event);
|
GdkEventGrabBroken * event);
|
||||||
static gint gtk_button_key_release (GtkWidget * widget, GdkEventKey * event);
|
static gint gtk_button_key_release (GtkWidget * widget, GdkEventKey * event);
|
||||||
@@ -209,6 +211,7 @@ gtk_button_class_init (GtkButtonClass *klass)
|
|||||||
widget_class->draw = gtk_button_draw;
|
widget_class->draw = gtk_button_draw;
|
||||||
widget_class->button_press_event = gtk_button_button_press;
|
widget_class->button_press_event = gtk_button_button_press;
|
||||||
widget_class->button_release_event = gtk_button_button_release;
|
widget_class->button_release_event = gtk_button_button_release;
|
||||||
|
widget_class->touch_event = gtk_button_touch;
|
||||||
widget_class->grab_broken_event = gtk_button_grab_broken;
|
widget_class->grab_broken_event = gtk_button_grab_broken;
|
||||||
widget_class->key_release_event = gtk_button_key_release;
|
widget_class->key_release_event = gtk_button_key_release;
|
||||||
widget_class->enter_notify_event = gtk_button_enter_notify;
|
widget_class->enter_notify_event = gtk_button_enter_notify;
|
||||||
@@ -1431,9 +1434,10 @@ gtk_button_realize (GtkWidget *widget)
|
|||||||
attributes.wclass = GDK_INPUT_ONLY;
|
attributes.wclass = GDK_INPUT_ONLY;
|
||||||
attributes.event_mask = gtk_widget_get_events (widget);
|
attributes.event_mask = gtk_widget_get_events (widget);
|
||||||
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
||||||
GDK_BUTTON_RELEASE_MASK |
|
GDK_BUTTON_RELEASE_MASK |
|
||||||
GDK_ENTER_NOTIFY_MASK |
|
GDK_TOUCH_MASK |
|
||||||
GDK_LEAVE_NOTIFY_MASK);
|
GDK_ENTER_NOTIFY_MASK |
|
||||||
|
GDK_LEAVE_NOTIFY_MASK);
|
||||||
|
|
||||||
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
||||||
|
|
||||||
@@ -1843,6 +1847,28 @@ gtk_button_button_release (GtkWidget *widget,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_button_touch (GtkWidget *widget,
|
||||||
|
GdkEventTouch *event)
|
||||||
|
{
|
||||||
|
GtkButton *button = GTK_BUTTON (widget);
|
||||||
|
GtkButtonPrivate *priv = button->priv;
|
||||||
|
|
||||||
|
if (event->type == GDK_TOUCH_BEGIN)
|
||||||
|
{
|
||||||
|
if (priv->focus_on_click && !gtk_widget_has_focus (widget))
|
||||||
|
gtk_widget_grab_focus (widget);
|
||||||
|
|
||||||
|
g_signal_emit (button, button_signals[PRESSED], 0);
|
||||||
|
}
|
||||||
|
else if (event->type == GDK_TOUCH_END)
|
||||||
|
{
|
||||||
|
g_signal_emit (button, button_signals[RELEASED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_button_grab_broken (GtkWidget *widget,
|
gtk_button_grab_broken (GtkWidget *widget,
|
||||||
GdkEventGrabBroken *event)
|
GdkEventGrabBroken *event)
|
||||||
@@ -1932,6 +1958,40 @@ gtk_real_button_pressed (GtkButton *button)
|
|||||||
gtk_button_update_state (button);
|
gtk_button_update_state (button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
touch_release_in_button (GtkButton *button)
|
||||||
|
{
|
||||||
|
GtkButtonPrivate *priv;
|
||||||
|
gint width, height;
|
||||||
|
GdkEvent *event;
|
||||||
|
gdouble x, y;
|
||||||
|
|
||||||
|
priv = button->priv;
|
||||||
|
event = gtk_get_current_event ();
|
||||||
|
|
||||||
|
if (!event)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (event->type != GDK_TOUCH_END ||
|
||||||
|
event->touch.window != priv->event_window)
|
||||||
|
{
|
||||||
|
gdk_event_free (event);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdk_event_get_coords (event, &x, &y);
|
||||||
|
width = gdk_window_get_width (priv->event_window);
|
||||||
|
height = gdk_window_get_height (priv->event_window);
|
||||||
|
|
||||||
|
gdk_event_free (event);
|
||||||
|
|
||||||
|
if (x >= 0 && x <= width &&
|
||||||
|
y >= 0 && y <= height)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_real_button_released (GtkButton *button)
|
gtk_real_button_released (GtkButton *button)
|
||||||
{
|
{
|
||||||
@@ -1944,7 +2004,8 @@ gtk_real_button_released (GtkButton *button)
|
|||||||
if (priv->activate_timeout)
|
if (priv->activate_timeout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->in_button)
|
if (priv->in_button ||
|
||||||
|
touch_release_in_button (button))
|
||||||
gtk_button_clicked (button);
|
gtk_button_clicked (button);
|
||||||
|
|
||||||
gtk_button_update_state (button);
|
gtk_button_update_state (button);
|
||||||
|
|||||||
251
gtk/gtkmain.c
251
gtk/gtkmain.c
@@ -1341,6 +1341,14 @@ rewrite_event_for_window (GdkEvent *event,
|
|||||||
new_window,
|
new_window,
|
||||||
&event->motion.x, &event->motion.y);
|
&event->motion.x, &event->motion.y);
|
||||||
break;
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
rewrite_events_translate (event->any.window,
|
||||||
|
new_window,
|
||||||
|
&event->touch.x, &event->touch.y);
|
||||||
|
break;
|
||||||
case GDK_KEY_PRESS:
|
case GDK_KEY_PRESS:
|
||||||
case GDK_KEY_RELEASE:
|
case GDK_KEY_RELEASE:
|
||||||
case GDK_PROXIMITY_IN:
|
case GDK_PROXIMITY_IN:
|
||||||
@@ -1386,6 +1394,10 @@ rewrite_event_for_grabs (GdkEvent *event)
|
|||||||
case GDK_PROXIMITY_OUT:
|
case GDK_PROXIMITY_OUT:
|
||||||
case GDK_KEY_PRESS:
|
case GDK_KEY_PRESS:
|
||||||
case GDK_KEY_RELEASE:
|
case GDK_KEY_RELEASE:
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
display = gdk_window_get_display (event->any.window);
|
display = gdk_window_get_display (event->any.window);
|
||||||
device = gdk_event_get_device (event);
|
device = gdk_event_get_device (event);
|
||||||
|
|
||||||
@@ -1473,6 +1485,7 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
{
|
{
|
||||||
GtkWidget *event_widget;
|
GtkWidget *event_widget;
|
||||||
GtkWidget *grab_widget = NULL;
|
GtkWidget *grab_widget = NULL;
|
||||||
|
GtkWidget *topmost_widget = NULL;
|
||||||
GtkWindowGroup *window_group;
|
GtkWindowGroup *window_group;
|
||||||
GdkEvent *rewritten_event = NULL;
|
GdkEvent *rewritten_event = NULL;
|
||||||
GdkDevice *device;
|
GdkDevice *device;
|
||||||
@@ -1532,6 +1545,14 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
if (!grab_widget)
|
if (!grab_widget)
|
||||||
grab_widget = gtk_window_group_get_current_grab (window_group);
|
grab_widget = gtk_window_group_get_current_grab (window_group);
|
||||||
|
|
||||||
|
/* Find out the topmost widget where captured event propagation
|
||||||
|
* should start, which is the widget holding the GTK+ grab
|
||||||
|
* if any, otherwise it's left NULL and events are emitted
|
||||||
|
* from the toplevel (or topmost parentless parent).
|
||||||
|
*/
|
||||||
|
if (grab_widget)
|
||||||
|
topmost_widget = grab_widget;
|
||||||
|
|
||||||
/* If the grab widget is an ancestor of the event widget
|
/* If the grab widget is an ancestor of the event widget
|
||||||
* then we send the event to the original event widget.
|
* then we send the event to the original event widget.
|
||||||
* This is the key to implementing modality.
|
* This is the key to implementing modality.
|
||||||
@@ -1628,14 +1649,17 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
case GDK_WINDOW_STATE:
|
case GDK_WINDOW_STATE:
|
||||||
case GDK_GRAB_BROKEN:
|
case GDK_GRAB_BROKEN:
|
||||||
case GDK_DAMAGE:
|
case GDK_DAMAGE:
|
||||||
gtk_widget_event (event_widget, event);
|
if (!_gtk_widget_captured_event (event_widget, event))
|
||||||
|
gtk_widget_event (event_widget, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
case GDK_BUTTON_PRESS:
|
case GDK_BUTTON_PRESS:
|
||||||
case GDK_2BUTTON_PRESS:
|
case GDK_2BUTTON_PRESS:
|
||||||
case GDK_3BUTTON_PRESS:
|
case GDK_3BUTTON_PRESS:
|
||||||
gtk_propagate_event (grab_widget, event);
|
case GDK_TOUCH_BEGIN:
|
||||||
|
if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
|
||||||
|
gtk_propagate_event (grab_widget, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_KEY_PRESS:
|
case GDK_KEY_PRESS:
|
||||||
@@ -1684,7 +1708,11 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
case GDK_PROXIMITY_IN:
|
case GDK_PROXIMITY_IN:
|
||||||
case GDK_PROXIMITY_OUT:
|
case GDK_PROXIMITY_OUT:
|
||||||
gtk_propagate_event (grab_widget, event);
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
|
||||||
|
gtk_propagate_event (grab_widget, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
@@ -1693,7 +1721,8 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
_gtk_widget_set_device_window (event_widget,
|
_gtk_widget_set_device_window (event_widget,
|
||||||
gdk_event_get_device (event),
|
gdk_event_get_device (event),
|
||||||
event->any.window);
|
event->any.window);
|
||||||
if (gtk_widget_is_sensitive (grab_widget))
|
if (gtk_widget_is_sensitive (grab_widget) &&
|
||||||
|
!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
|
||||||
gtk_widget_event (grab_widget, event);
|
gtk_widget_event (grab_widget, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1703,7 +1732,8 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
_gtk_widget_set_device_window (event_widget,
|
_gtk_widget_set_device_window (event_widget,
|
||||||
gdk_event_get_device (event),
|
gdk_event_get_device (event),
|
||||||
NULL);
|
NULL);
|
||||||
if (gtk_widget_is_sensitive (grab_widget))
|
if (gtk_widget_is_sensitive (grab_widget) &&
|
||||||
|
!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
|
||||||
gtk_widget_event (grab_widget, event);
|
gtk_widget_event (grab_widget, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1731,6 +1761,7 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
|| event->type == GDK_DRAG_ENTER
|
|| event->type == GDK_DRAG_ENTER
|
||||||
|| event->type == GDK_GRAB_BROKEN
|
|| event->type == GDK_GRAB_BROKEN
|
||||||
|| event->type == GDK_MOTION_NOTIFY
|
|| event->type == GDK_MOTION_NOTIFY
|
||||||
|
|| event->type == GDK_TOUCH_UPDATE
|
||||||
|| event->type == GDK_SCROLL)
|
|| event->type == GDK_SCROLL)
|
||||||
{
|
{
|
||||||
_gtk_tooltip_handle_event (event);
|
_gtk_tooltip_handle_event (event);
|
||||||
@@ -2333,6 +2364,135 @@ gtk_get_event_widget (GdkEvent *event)
|
|||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
propagate_event_up (GtkWidget *widget,
|
||||||
|
GdkEvent *event,
|
||||||
|
GtkWidget *topmost)
|
||||||
|
{
|
||||||
|
gboolean handled_event = FALSE;
|
||||||
|
|
||||||
|
/* Propagate event up the widget tree so that
|
||||||
|
* parents can see the button and motion
|
||||||
|
* events of the children.
|
||||||
|
*/
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
GtkWidget *tmp;
|
||||||
|
|
||||||
|
g_object_ref (widget);
|
||||||
|
|
||||||
|
/* Scroll events are special cased here because it
|
||||||
|
* feels wrong when scrolling a GtkViewport, say,
|
||||||
|
* to have children of the viewport eat the scroll
|
||||||
|
* event
|
||||||
|
*/
|
||||||
|
if (!gtk_widget_is_sensitive (widget))
|
||||||
|
handled_event = event->type != GDK_SCROLL;
|
||||||
|
else
|
||||||
|
handled_event = gtk_widget_event (widget, event);
|
||||||
|
|
||||||
|
tmp = gtk_widget_get_parent (widget);
|
||||||
|
g_object_unref (widget);
|
||||||
|
|
||||||
|
if (widget == topmost)
|
||||||
|
break;
|
||||||
|
|
||||||
|
widget = tmp;
|
||||||
|
|
||||||
|
if (handled_event || !widget)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handled_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
propagate_event_down (GtkWidget *widget,
|
||||||
|
GdkEvent *event,
|
||||||
|
GtkWidget *topmost)
|
||||||
|
{
|
||||||
|
gint handled_event = FALSE;
|
||||||
|
GList *widgets = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
widgets = g_list_prepend (widgets, g_object_ref (widget));
|
||||||
|
while (widget && widget != topmost)
|
||||||
|
{
|
||||||
|
widget = gtk_widget_get_parent (widget);
|
||||||
|
if (!widget)
|
||||||
|
break;
|
||||||
|
|
||||||
|
widgets = g_list_prepend (widgets, g_object_ref (widget));
|
||||||
|
|
||||||
|
if (widget == topmost)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = widgets; l && !handled_event; l = g_list_next (l))
|
||||||
|
{
|
||||||
|
widget = (GtkWidget *)l->data;
|
||||||
|
|
||||||
|
if (!gtk_widget_is_sensitive (widget))
|
||||||
|
handled_event = TRUE;
|
||||||
|
else
|
||||||
|
handled_event = _gtk_widget_captured_event (widget, event);
|
||||||
|
}
|
||||||
|
g_list_free_full (widgets, (GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
|
return handled_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
propagate_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event,
|
||||||
|
gboolean captured,
|
||||||
|
GtkWidget *topmost)
|
||||||
|
{
|
||||||
|
gboolean handled_event = FALSE;
|
||||||
|
gboolean (* propagate_func) (GtkWidget *widget, GdkEvent *event);
|
||||||
|
|
||||||
|
propagate_func = captured ? _gtk_widget_captured_event : gtk_widget_event;
|
||||||
|
|
||||||
|
if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE)
|
||||||
|
{
|
||||||
|
/* Only send key events within Window widgets to the Window
|
||||||
|
* The Window widget will in turn pass the
|
||||||
|
* key event on to the currently focused widget
|
||||||
|
* for that window.
|
||||||
|
*/
|
||||||
|
GtkWidget *window;
|
||||||
|
|
||||||
|
window = gtk_widget_get_toplevel (widget);
|
||||||
|
if (GTK_IS_WINDOW (window))
|
||||||
|
{
|
||||||
|
g_object_ref (widget);
|
||||||
|
/* If there is a grab within the window, give the grab widget
|
||||||
|
* a first crack at the key event
|
||||||
|
*/
|
||||||
|
if (widget != window && gtk_widget_has_grab (widget))
|
||||||
|
handled_event = propagate_func (widget, event);
|
||||||
|
|
||||||
|
if (!handled_event)
|
||||||
|
{
|
||||||
|
window = gtk_widget_get_toplevel (widget);
|
||||||
|
if (GTK_IS_WINDOW (window))
|
||||||
|
{
|
||||||
|
if (gtk_widget_is_sensitive (window))
|
||||||
|
handled_event = propagate_func (window, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (widget);
|
||||||
|
return handled_event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other events get propagated up/down the widget tree */
|
||||||
|
return captured ?
|
||||||
|
propagate_event_down (widget, event, topmost) :
|
||||||
|
propagate_event_up (widget, event, topmost);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_propagate_event:
|
* gtk_propagate_event:
|
||||||
* @widget: a #GtkWidget
|
* @widget: a #GtkWidget
|
||||||
@@ -2361,79 +2521,16 @@ void
|
|||||||
gtk_propagate_event (GtkWidget *widget,
|
gtk_propagate_event (GtkWidget *widget,
|
||||||
GdkEvent *event)
|
GdkEvent *event)
|
||||||
{
|
{
|
||||||
gint handled_event;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||||
g_return_if_fail (event != NULL);
|
g_return_if_fail (event != NULL);
|
||||||
|
|
||||||
handled_event = FALSE;
|
propagate_event (widget, event, FALSE, NULL);
|
||||||
|
}
|
||||||
g_object_ref (widget);
|
|
||||||
|
gboolean
|
||||||
if ((event->type == GDK_KEY_PRESS) ||
|
_gtk_propagate_captured_event (GtkWidget *widget,
|
||||||
(event->type == GDK_KEY_RELEASE))
|
GdkEvent *event,
|
||||||
{
|
GtkWidget *topmost)
|
||||||
/* Only send key events within Window widgets to the Window
|
{
|
||||||
* The Window widget will in turn pass the
|
return propagate_event (widget, event, TRUE, topmost);
|
||||||
* key event on to the currently focused widget
|
|
||||||
* for that window.
|
|
||||||
*/
|
|
||||||
GtkWidget *window;
|
|
||||||
|
|
||||||
window = gtk_widget_get_toplevel (widget);
|
|
||||||
if (GTK_IS_WINDOW (window))
|
|
||||||
{
|
|
||||||
/* If there is a grab within the window, give the grab widget
|
|
||||||
* a first crack at the key event
|
|
||||||
*/
|
|
||||||
if (widget != window && gtk_widget_has_grab (widget))
|
|
||||||
handled_event = gtk_widget_event (widget, event);
|
|
||||||
|
|
||||||
if (!handled_event)
|
|
||||||
{
|
|
||||||
window = gtk_widget_get_toplevel (widget);
|
|
||||||
if (GTK_IS_WINDOW (window))
|
|
||||||
{
|
|
||||||
if (gtk_widget_is_sensitive (window))
|
|
||||||
gtk_widget_event (window, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handled_event = TRUE; /* don't send to widget */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Other events get propagated up the widget tree
|
|
||||||
* so that parents can see the button and motion
|
|
||||||
* events of the children.
|
|
||||||
*/
|
|
||||||
if (!handled_event)
|
|
||||||
{
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
GtkWidget *tmp;
|
|
||||||
|
|
||||||
/* Scroll events are special cased here because it
|
|
||||||
* feels wrong when scrolling a GtkViewport, say,
|
|
||||||
* to have children of the viewport eat the scroll
|
|
||||||
* event
|
|
||||||
*/
|
|
||||||
if (!gtk_widget_is_sensitive (widget))
|
|
||||||
handled_event = event->type != GDK_SCROLL;
|
|
||||||
else
|
|
||||||
handled_event = gtk_widget_event (widget, event);
|
|
||||||
|
|
||||||
tmp = gtk_widget_get_parent (widget);
|
|
||||||
g_object_unref (widget);
|
|
||||||
|
|
||||||
widget = tmp;
|
|
||||||
|
|
||||||
if (!handled_event && widget)
|
|
||||||
g_object_ref (widget);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_object_unref (widget);
|
|
||||||
}
|
}
|
||||||
|
|||||||
511
gtk/gtkmenu.c
511
gtk/gtkmenu.c
@@ -110,8 +110,10 @@
|
|||||||
#include "gtksettings.h"
|
#include "gtksettings.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
#include "gtkwidgetprivate.h"
|
#include "gtkwidgetprivate.h"
|
||||||
|
#include "gtkdnd.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtktypebuiltins.h"
|
#include "gtktypebuiltins.h"
|
||||||
|
#include "gtkwidgetprivate.h"
|
||||||
|
|
||||||
#include "deprecated/gtktearoffmenuitem.h"
|
#include "deprecated/gtktearoffmenuitem.h"
|
||||||
|
|
||||||
@@ -227,12 +229,13 @@ static void gtk_menu_scroll_to (GtkMenu *menu,
|
|||||||
gint offset);
|
gint offset);
|
||||||
static void gtk_menu_grab_notify (GtkWidget *widget,
|
static void gtk_menu_grab_notify (GtkWidget *widget,
|
||||||
gboolean was_grabbed);
|
gboolean was_grabbed);
|
||||||
|
static gboolean gtk_menu_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event);
|
||||||
|
|
||||||
|
|
||||||
static void gtk_menu_stop_scrolling (GtkMenu *menu);
|
static void gtk_menu_stop_scrolling (GtkMenu *menu);
|
||||||
static void gtk_menu_remove_scroll_timeout (GtkMenu *menu);
|
static void gtk_menu_remove_scroll_timeout (GtkMenu *menu);
|
||||||
static gboolean gtk_menu_scroll_timeout (gpointer data);
|
static gboolean gtk_menu_scroll_timeout (gpointer data);
|
||||||
static gboolean gtk_menu_scroll_timeout_initial (gpointer data);
|
|
||||||
static void gtk_menu_start_scrolling (GtkMenu *menu);
|
|
||||||
|
|
||||||
static void gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell,
|
static void gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell,
|
||||||
GtkWidget *menu_item);
|
GtkWidget *menu_item);
|
||||||
@@ -1057,9 +1060,12 @@ gtk_menu_init (GtkMenu *menu)
|
|||||||
priv->needs_destruction_ref = TRUE;
|
priv->needs_destruction_ref = TRUE;
|
||||||
|
|
||||||
priv->monitor_num = -1;
|
priv->monitor_num = -1;
|
||||||
|
priv->drag_start_y = -1;
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (GTK_WIDGET (menu));
|
context = gtk_widget_get_style_context (GTK_WIDGET (menu));
|
||||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_MENU);
|
gtk_style_context_add_class (context, GTK_STYLE_CLASS_MENU);
|
||||||
|
|
||||||
|
_gtk_widget_set_captured_event_handler (GTK_WIDGET (menu), gtk_menu_captured_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1465,7 +1471,7 @@ gtk_menu_popup_for_device (GtkMenu *menu,
|
|||||||
GtkMenuShell *menu_shell;
|
GtkMenuShell *menu_shell;
|
||||||
gboolean grab_keyboard;
|
gboolean grab_keyboard;
|
||||||
GtkWidget *parent_toplevel;
|
GtkWidget *parent_toplevel;
|
||||||
GdkDevice *keyboard, *pointer;
|
GdkDevice *keyboard, *pointer, *source_device = NULL;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_MENU (menu));
|
g_return_if_fail (GTK_IS_MENU (menu));
|
||||||
g_return_if_fail (device == NULL || GDK_IS_DEVICE (device));
|
g_return_if_fail (device == NULL || GDK_IS_DEVICE (device));
|
||||||
@@ -1602,6 +1608,7 @@ gtk_menu_popup_for_device (GtkMenu *menu,
|
|||||||
(current_event->type != GDK_ENTER_NOTIFY))
|
(current_event->type != GDK_ENTER_NOTIFY))
|
||||||
menu_shell->priv->ignore_enter = TRUE;
|
menu_shell->priv->ignore_enter = TRUE;
|
||||||
|
|
||||||
|
source_device = gdk_event_get_source_device (current_event);
|
||||||
gdk_event_free (current_event);
|
gdk_event_free (current_event);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1671,17 +1678,9 @@ gtk_menu_popup_for_device (GtkMenu *menu,
|
|||||||
gtk_menu_scroll_to (menu, priv->scroll_offset);
|
gtk_menu_scroll_to (menu, priv->scroll_offset);
|
||||||
|
|
||||||
/* if no item is selected, select the first one */
|
/* if no item is selected, select the first one */
|
||||||
if (!menu_shell->priv->active_menu_item)
|
if (!menu_shell->priv->active_menu_item &&
|
||||||
{
|
source_device && gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
|
||||||
gboolean touchscreen_mode;
|
gtk_menu_shell_select_first (menu_shell, TRUE);
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (touchscreen_mode)
|
|
||||||
gtk_menu_shell_select_first (menu_shell, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Once everything is set up correctly, map the toplevel */
|
/* Once everything is set up correctly, map the toplevel */
|
||||||
gtk_widget_show (priv->toplevel);
|
gtk_widget_show (priv->toplevel);
|
||||||
@@ -3316,34 +3315,6 @@ gtk_menu_get_preferred_height_for_width (GtkWidget *widget,
|
|||||||
g_free (nat_heights);
|
g_free (nat_heights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gtk_menu_button_scroll (GtkMenu *menu,
|
|
||||||
GdkEventButton *event)
|
|
||||||
{
|
|
||||||
GtkMenuPrivate *priv = menu->priv;
|
|
||||||
|
|
||||||
if (priv->upper_arrow_prelight || priv->lower_arrow_prelight)
|
|
||||||
{
|
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (touchscreen_mode)
|
|
||||||
gtk_menu_handle_scrolling (menu,
|
|
||||||
event->x_root, event->y_root,
|
|
||||||
event->type == GDK_BUTTON_PRESS,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pointer_in_menu_window (GtkWidget *widget,
|
pointer_in_menu_window (GtkWidget *widget,
|
||||||
gdouble x_root,
|
gdouble x_root,
|
||||||
@@ -3380,13 +3351,16 @@ static gboolean
|
|||||||
gtk_menu_button_press (GtkWidget *widget,
|
gtk_menu_button_press (GtkWidget *widget,
|
||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
{
|
{
|
||||||
|
GdkDevice *source_device;
|
||||||
|
GtkWidget *event_widget;
|
||||||
|
GtkMenu *menu;
|
||||||
|
|
||||||
if (event->type != GDK_BUTTON_PRESS)
|
if (event->type != GDK_BUTTON_PRESS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Don't pass down to menu shell for presses over scroll arrows
|
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||||
*/
|
event_widget = gtk_get_event_widget ((GdkEvent *) event);
|
||||||
if (gtk_menu_button_scroll (GTK_MENU (widget), event))
|
menu = GTK_MENU (widget);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Don't pass down to menu shell if a non-menuitem part of the menu
|
/* Don't pass down to menu shell if a non-menuitem part of the menu
|
||||||
* was clicked. The check for the event_widget being a GtkMenuShell
|
* was clicked. The check for the event_widget being a GtkMenuShell
|
||||||
@@ -3395,10 +3369,16 @@ gtk_menu_button_press (GtkWidget *widget,
|
|||||||
* the menu or on its border are delivered relative to
|
* the menu or on its border are delivered relative to
|
||||||
* menu_shell->window.
|
* menu_shell->window.
|
||||||
*/
|
*/
|
||||||
if (GTK_IS_MENU_SHELL (gtk_get_event_widget ((GdkEvent *) event)) &&
|
if (GTK_IS_MENU_SHELL (event_widget) &&
|
||||||
pointer_in_menu_window (widget, event->x_root, event->y_root))
|
pointer_in_menu_window (widget, event->x_root, event->y_root))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
if (GTK_IS_MENU_ITEM (event_widget) &&
|
||||||
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN &&
|
||||||
|
GTK_MENU_ITEM (event_widget)->priv->submenu != NULL &&
|
||||||
|
!gtk_widget_is_drawable (GTK_MENU_ITEM (event_widget)->priv->submenu))
|
||||||
|
menu->priv->ignore_button_release = TRUE;
|
||||||
|
|
||||||
return GTK_WIDGET_CLASS (gtk_menu_parent_class)->button_press_event (widget, event);
|
return GTK_WIDGET_CLASS (gtk_menu_parent_class)->button_press_event (widget, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3417,11 +3397,6 @@ gtk_menu_button_release (GtkWidget *widget,
|
|||||||
if (event->type != GDK_BUTTON_RELEASE)
|
if (event->type != GDK_BUTTON_RELEASE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Don't pass down to menu shell for releases over scroll arrows
|
|
||||||
*/
|
|
||||||
if (gtk_menu_button_scroll (GTK_MENU (widget), event))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Don't pass down to menu shell if a non-menuitem part of the menu
|
/* Don't pass down to menu shell if a non-menuitem part of the menu
|
||||||
* was clicked (see comment in button_press()).
|
* was clicked (see comment in button_press()).
|
||||||
*/
|
*/
|
||||||
@@ -3665,10 +3640,14 @@ gtk_menu_motion_notify (GtkWidget *widget,
|
|||||||
GtkMenu *menu;
|
GtkMenu *menu;
|
||||||
GtkMenuShell *menu_shell;
|
GtkMenuShell *menu_shell;
|
||||||
GtkWidget *parent;
|
GtkWidget *parent;
|
||||||
|
GdkDevice *source_device;
|
||||||
|
|
||||||
gboolean need_enter;
|
gboolean need_enter;
|
||||||
|
|
||||||
if (GTK_IS_MENU (widget))
|
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||||
|
|
||||||
|
if (GTK_IS_MENU (widget) &&
|
||||||
|
gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
|
||||||
{
|
{
|
||||||
GtkMenuPrivate *priv = GTK_MENU(widget)->priv;
|
GtkMenuPrivate *priv = GTK_MENU(widget)->priv;
|
||||||
|
|
||||||
@@ -3832,90 +3811,17 @@ gtk_menu_scroll_by (GtkMenu *menu,
|
|||||||
gtk_menu_scroll_to (menu, offset);
|
gtk_menu_scroll_to (menu, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_menu_do_timeout_scroll (GtkMenu *menu,
|
|
||||||
gboolean touchscreen_mode)
|
|
||||||
{
|
|
||||||
GtkMenuPrivate *priv = menu->priv;
|
|
||||||
gboolean upper_visible;
|
|
||||||
gboolean lower_visible;
|
|
||||||
|
|
||||||
upper_visible = priv->upper_arrow_visible;
|
|
||||||
lower_visible = priv->lower_arrow_visible;
|
|
||||||
|
|
||||||
gtk_menu_scroll_by (menu, priv->scroll_step);
|
|
||||||
|
|
||||||
if (touchscreen_mode &&
|
|
||||||
(upper_visible != priv->upper_arrow_visible ||
|
|
||||||
lower_visible != priv->lower_arrow_visible))
|
|
||||||
{
|
|
||||||
/* We are about to hide a scroll arrow while the mouse is pressed,
|
|
||||||
* this would cause the uncovered menu item to be activated on button
|
|
||||||
* release. Therefore we need to ignore button release here
|
|
||||||
*/
|
|
||||||
GTK_MENU_SHELL (menu)->priv->ignore_enter = TRUE;
|
|
||||||
priv->ignore_button_release = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_menu_scroll_timeout (gpointer data)
|
gtk_menu_scroll_timeout (gpointer data)
|
||||||
{
|
{
|
||||||
GtkMenu *menu;
|
GtkMenu *menu;
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
menu = GTK_MENU (data);
|
menu = GTK_MENU (data);
|
||||||
|
gtk_menu_scroll_by (menu, menu->priv->scroll_step);
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gtk_menu_do_timeout_scroll (menu, touchscreen_mode);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gtk_menu_scroll_timeout_initial (gpointer data)
|
|
||||||
{
|
|
||||||
GtkMenu *menu;
|
|
||||||
guint timeout;
|
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
menu = GTK_MENU (data);
|
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
|
||||||
"gtk-timeout-repeat", &timeout,
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gtk_menu_do_timeout_scroll (menu, touchscreen_mode);
|
|
||||||
|
|
||||||
gtk_menu_remove_scroll_timeout (menu);
|
|
||||||
|
|
||||||
menu->priv->scroll_timeout =
|
|
||||||
gdk_threads_add_timeout (timeout, gtk_menu_scroll_timeout, menu);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_menu_start_scrolling (GtkMenu *menu)
|
|
||||||
{
|
|
||||||
guint timeout;
|
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
|
||||||
"gtk-timeout-repeat", &timeout,
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gtk_menu_do_timeout_scroll (menu, touchscreen_mode);
|
|
||||||
|
|
||||||
menu->priv->scroll_timeout =
|
|
||||||
gdk_threads_add_timeout (timeout, gtk_menu_scroll_timeout_initial, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_menu_scroll (GtkWidget *widget,
|
gtk_menu_scroll (GtkWidget *widget,
|
||||||
GdkEventScroll *event)
|
GdkEventScroll *event)
|
||||||
@@ -4039,14 +3945,9 @@ gtk_menu_handle_scrolling (GtkMenu *menu,
|
|||||||
gboolean in_arrow;
|
gboolean in_arrow;
|
||||||
gboolean scroll_fast = FALSE;
|
gboolean scroll_fast = FALSE;
|
||||||
gint top_x, top_y;
|
gint top_x, top_y;
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
menu_shell = GTK_MENU_SHELL (menu);
|
menu_shell = GTK_MENU_SHELL (menu);
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gdk_window_get_position (gtk_widget_get_window (priv->toplevel),
|
gdk_window_get_position (gtk_widget_get_window (priv->toplevel),
|
||||||
&top_x, &top_y);
|
&top_x, &top_y);
|
||||||
x -= top_x;
|
x -= top_x;
|
||||||
@@ -4064,82 +3965,44 @@ gtk_menu_handle_scrolling (GtkMenu *menu,
|
|||||||
in_arrow = TRUE;
|
in_arrow = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touchscreen_mode)
|
|
||||||
priv->upper_arrow_prelight = in_arrow;
|
|
||||||
|
|
||||||
if ((priv->upper_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
if ((priv->upper_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
||||||
{
|
{
|
||||||
gboolean arrow_pressed = FALSE;
|
gboolean arrow_pressed = FALSE;
|
||||||
|
|
||||||
if (priv->upper_arrow_visible && !priv->tearoff_active)
|
if (priv->upper_arrow_visible && !priv->tearoff_active)
|
||||||
{
|
{
|
||||||
if (touchscreen_mode)
|
scroll_fast = (y < rect.y + MENU_SCROLL_FAST_ZONE);
|
||||||
|
|
||||||
|
if (enter && in_arrow &&
|
||||||
|
(!priv->upper_arrow_prelight ||
|
||||||
|
priv->scroll_fast != scroll_fast))
|
||||||
{
|
{
|
||||||
if (enter && priv->upper_arrow_prelight)
|
priv->upper_arrow_prelight = TRUE;
|
||||||
{
|
priv->scroll_fast = scroll_fast;
|
||||||
if (priv->scroll_timeout == 0)
|
|
||||||
{
|
|
||||||
/* Deselect the active item so that
|
|
||||||
* any submenus are popped down
|
|
||||||
*/
|
|
||||||
gtk_menu_shell_deselect (menu_shell);
|
|
||||||
|
|
||||||
gtk_menu_remove_scroll_timeout (menu);
|
/* Deselect the active item so that
|
||||||
priv->scroll_step = -MENU_SCROLL_STEP2; /* always fast */
|
* any submenus are popped down
|
||||||
|
*/
|
||||||
|
gtk_menu_shell_deselect (menu_shell);
|
||||||
|
|
||||||
if (!motion)
|
gtk_menu_remove_scroll_timeout (menu);
|
||||||
{
|
priv->scroll_step = scroll_fast
|
||||||
/* Only do stuff on click. */
|
? -MENU_SCROLL_STEP2
|
||||||
gtk_menu_start_scrolling (menu);
|
: -MENU_SCROLL_STEP1;
|
||||||
arrow_pressed = TRUE;
|
|
||||||
}
|
priv->scroll_timeout =
|
||||||
}
|
gdk_threads_add_timeout (scroll_fast
|
||||||
else
|
? MENU_SCROLL_TIMEOUT2
|
||||||
{
|
: MENU_SCROLL_TIMEOUT1,
|
||||||
arrow_pressed = TRUE;
|
gtk_menu_scroll_timeout, menu);
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!enter)
|
|
||||||
{
|
|
||||||
gtk_menu_stop_scrolling (menu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* !touchscreen_mode */
|
else if (!enter && !in_arrow && priv->upper_arrow_prelight)
|
||||||
{
|
{
|
||||||
scroll_fast = (y < rect.y + MENU_SCROLL_FAST_ZONE);
|
gtk_menu_stop_scrolling (menu);
|
||||||
|
|
||||||
if (enter && in_arrow &&
|
|
||||||
(!priv->upper_arrow_prelight ||
|
|
||||||
priv->scroll_fast != scroll_fast))
|
|
||||||
{
|
|
||||||
priv->upper_arrow_prelight = TRUE;
|
|
||||||
priv->scroll_fast = scroll_fast;
|
|
||||||
|
|
||||||
/* Deselect the active item so that
|
|
||||||
* any submenus are popped down
|
|
||||||
*/
|
|
||||||
gtk_menu_shell_deselect (menu_shell);
|
|
||||||
|
|
||||||
gtk_menu_remove_scroll_timeout (menu);
|
|
||||||
priv->scroll_step = scroll_fast
|
|
||||||
? -MENU_SCROLL_STEP2
|
|
||||||
: -MENU_SCROLL_STEP1;
|
|
||||||
|
|
||||||
priv->scroll_timeout =
|
|
||||||
gdk_threads_add_timeout (scroll_fast
|
|
||||||
? MENU_SCROLL_TIMEOUT2
|
|
||||||
: MENU_SCROLL_TIMEOUT1,
|
|
||||||
gtk_menu_scroll_timeout, menu);
|
|
||||||
}
|
|
||||||
else if (!enter && !in_arrow && priv->upper_arrow_prelight)
|
|
||||||
{
|
|
||||||
gtk_menu_stop_scrolling (menu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtk_menu_start_scrolling() might have hit the top of the
|
/* check if the button isn't insensitive before
|
||||||
* menu, so check if the button isn't insensitive before
|
|
||||||
* changing it to something else.
|
* changing it to something else.
|
||||||
*/
|
*/
|
||||||
if ((priv->upper_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
if ((priv->upper_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
||||||
@@ -4174,82 +4037,44 @@ gtk_menu_handle_scrolling (GtkMenu *menu,
|
|||||||
in_arrow = TRUE;
|
in_arrow = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touchscreen_mode)
|
|
||||||
priv->lower_arrow_prelight = in_arrow;
|
|
||||||
|
|
||||||
if ((priv->lower_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
if ((priv->lower_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
||||||
{
|
{
|
||||||
gboolean arrow_pressed = FALSE;
|
gboolean arrow_pressed = FALSE;
|
||||||
|
|
||||||
if (priv->lower_arrow_visible && !priv->tearoff_active)
|
if (priv->lower_arrow_visible && !priv->tearoff_active)
|
||||||
{
|
{
|
||||||
if (touchscreen_mode)
|
scroll_fast = (y > rect.y + rect.height - MENU_SCROLL_FAST_ZONE);
|
||||||
|
|
||||||
|
if (enter && in_arrow &&
|
||||||
|
(!priv->lower_arrow_prelight ||
|
||||||
|
priv->scroll_fast != scroll_fast))
|
||||||
{
|
{
|
||||||
if (enter && priv->lower_arrow_prelight)
|
priv->lower_arrow_prelight = TRUE;
|
||||||
{
|
priv->scroll_fast = scroll_fast;
|
||||||
if (priv->scroll_timeout == 0)
|
|
||||||
{
|
|
||||||
/* Deselect the active item so that
|
|
||||||
* any submenus are popped down
|
|
||||||
*/
|
|
||||||
gtk_menu_shell_deselect (menu_shell);
|
|
||||||
|
|
||||||
gtk_menu_remove_scroll_timeout (menu);
|
/* Deselect the active item so that
|
||||||
priv->scroll_step = MENU_SCROLL_STEP2; /* always fast */
|
* any submenus are popped down
|
||||||
|
*/
|
||||||
|
gtk_menu_shell_deselect (menu_shell);
|
||||||
|
|
||||||
if (!motion)
|
gtk_menu_remove_scroll_timeout (menu);
|
||||||
{
|
priv->scroll_step = scroll_fast
|
||||||
/* Only do stuff on click. */
|
? MENU_SCROLL_STEP2
|
||||||
gtk_menu_start_scrolling (menu);
|
: MENU_SCROLL_STEP1;
|
||||||
arrow_pressed = TRUE;
|
|
||||||
}
|
priv->scroll_timeout =
|
||||||
}
|
gdk_threads_add_timeout (scroll_fast
|
||||||
else
|
? MENU_SCROLL_TIMEOUT2
|
||||||
{
|
: MENU_SCROLL_TIMEOUT1,
|
||||||
arrow_pressed = TRUE;
|
gtk_menu_scroll_timeout, menu);
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!enter)
|
|
||||||
{
|
|
||||||
gtk_menu_stop_scrolling (menu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* !touchscreen_mode */
|
else if (!enter && !in_arrow && priv->lower_arrow_prelight)
|
||||||
{
|
{
|
||||||
scroll_fast = (y > rect.y + rect.height - MENU_SCROLL_FAST_ZONE);
|
gtk_menu_stop_scrolling (menu);
|
||||||
|
|
||||||
if (enter && in_arrow &&
|
|
||||||
(!priv->lower_arrow_prelight ||
|
|
||||||
priv->scroll_fast != scroll_fast))
|
|
||||||
{
|
|
||||||
priv->lower_arrow_prelight = TRUE;
|
|
||||||
priv->scroll_fast = scroll_fast;
|
|
||||||
|
|
||||||
/* Deselect the active item so that
|
|
||||||
* any submenus are popped down
|
|
||||||
*/
|
|
||||||
gtk_menu_shell_deselect (menu_shell);
|
|
||||||
|
|
||||||
gtk_menu_remove_scroll_timeout (menu);
|
|
||||||
priv->scroll_step = scroll_fast
|
|
||||||
? MENU_SCROLL_STEP2
|
|
||||||
: MENU_SCROLL_STEP1;
|
|
||||||
|
|
||||||
priv->scroll_timeout =
|
|
||||||
gdk_threads_add_timeout (scroll_fast
|
|
||||||
? MENU_SCROLL_TIMEOUT2
|
|
||||||
: MENU_SCROLL_TIMEOUT1,
|
|
||||||
gtk_menu_scroll_timeout, menu);
|
|
||||||
}
|
|
||||||
else if (!enter && !in_arrow && priv->lower_arrow_prelight)
|
|
||||||
{
|
|
||||||
gtk_menu_stop_scrolling (menu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtk_menu_start_scrolling() might have hit the bottom of the
|
/* check if the button isn't insensitive before
|
||||||
* menu, so check if the button isn't insensitive before
|
|
||||||
* changing it to something else.
|
* changing it to something else.
|
||||||
*/
|
*/
|
||||||
if ((priv->lower_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
if ((priv->lower_arrow_state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
||||||
@@ -4279,19 +4104,18 @@ gtk_menu_enter_notify (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
GtkWidget *menu_item;
|
GtkWidget *menu_item;
|
||||||
GtkWidget *parent;
|
GtkWidget *parent;
|
||||||
gboolean touchscreen_mode;
|
GdkDevice *source_device;
|
||||||
|
|
||||||
if (event->mode == GDK_CROSSING_GTK_GRAB ||
|
if (event->mode == GDK_CROSSING_GTK_GRAB ||
|
||||||
event->mode == GDK_CROSSING_GTK_UNGRAB ||
|
event->mode == GDK_CROSSING_GTK_UNGRAB ||
|
||||||
event->mode == GDK_CROSSING_STATE_CHANGED)
|
event->mode == GDK_CROSSING_STATE_CHANGED)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (widget),
|
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
menu_item = gtk_get_event_widget ((GdkEvent*) event);
|
menu_item = gtk_get_event_widget ((GdkEvent*) event);
|
||||||
if (GTK_IS_MENU (widget))
|
|
||||||
|
if (GTK_IS_MENU (widget) &&
|
||||||
|
gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
|
||||||
{
|
{
|
||||||
GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
|
GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
|
||||||
|
|
||||||
@@ -4300,7 +4124,8 @@ gtk_menu_enter_notify (GtkWidget *widget,
|
|||||||
event->x_root, event->y_root, TRUE, TRUE);
|
event->x_root, event->y_root, TRUE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!touchscreen_mode && GTK_IS_MENU_ITEM (menu_item))
|
if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN &&
|
||||||
|
GTK_IS_MENU_ITEM (menu_item))
|
||||||
{
|
{
|
||||||
GtkWidget *menu = gtk_widget_get_parent (menu_item);
|
GtkWidget *menu = gtk_widget_get_parent (menu_item);
|
||||||
|
|
||||||
@@ -4357,6 +4182,7 @@ gtk_menu_leave_notify (GtkWidget *widget,
|
|||||||
GtkMenu *menu;
|
GtkMenu *menu;
|
||||||
GtkMenuItem *menu_item;
|
GtkMenuItem *menu_item;
|
||||||
GtkWidget *event_widget;
|
GtkWidget *event_widget;
|
||||||
|
GdkDevice *source_device;
|
||||||
|
|
||||||
if (event->mode == GDK_CROSSING_GTK_GRAB ||
|
if (event->mode == GDK_CROSSING_GTK_GRAB ||
|
||||||
event->mode == GDK_CROSSING_GTK_UNGRAB ||
|
event->mode == GDK_CROSSING_GTK_UNGRAB ||
|
||||||
@@ -4369,7 +4195,10 @@ gtk_menu_leave_notify (GtkWidget *widget,
|
|||||||
if (gtk_menu_navigating_submenu (menu, event->x_root, event->y_root))
|
if (gtk_menu_navigating_submenu (menu, event->x_root, event->y_root))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
gtk_menu_handle_scrolling (menu, event->x_root, event->y_root, FALSE, TRUE);
|
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||||
|
|
||||||
|
if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
|
||||||
|
gtk_menu_handle_scrolling (menu, event->x_root, event->y_root, FALSE, TRUE);
|
||||||
|
|
||||||
event_widget = gtk_get_event_widget ((GdkEvent*) event);
|
event_widget = gtk_get_event_widget ((GdkEvent*) event);
|
||||||
|
|
||||||
@@ -4404,6 +4233,142 @@ gtk_menu_leave_notify (GtkWidget *widget,
|
|||||||
return GTK_WIDGET_CLASS (gtk_menu_parent_class)->leave_notify_event (widget, event);
|
return GTK_WIDGET_CLASS (gtk_menu_parent_class)->leave_notify_event (widget, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
pointer_on_menu_widget (GtkMenu *menu,
|
||||||
|
gdouble x_root,
|
||||||
|
gdouble y_root)
|
||||||
|
{
|
||||||
|
GtkMenuPrivate *priv = menu->priv;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
gint window_x, window_y;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (GTK_WIDGET (menu), &allocation);
|
||||||
|
gdk_window_get_position (gtk_widget_get_window (priv->toplevel),
|
||||||
|
&window_x, &window_y);
|
||||||
|
|
||||||
|
if (x_root >= window_x && x_root < window_x + allocation.width &&
|
||||||
|
y_root >= window_y && y_root < window_y + allocation.height)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_menu_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event)
|
||||||
|
{
|
||||||
|
GdkDevice *source_device;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
GtkMenuPrivate *priv;
|
||||||
|
GtkMenu *menu;
|
||||||
|
gdouble x_root, y_root;
|
||||||
|
guint button;
|
||||||
|
GdkModifierType state;
|
||||||
|
|
||||||
|
menu = GTK_MENU (widget);
|
||||||
|
priv = menu->priv;
|
||||||
|
|
||||||
|
if (!priv->upper_arrow_visible && !priv->lower_arrow_visible)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
source_device = gdk_event_get_source_device (event);
|
||||||
|
gdk_event_get_root_coords (event, &x_root, &y_root);
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_BUTTON_PRESS:
|
||||||
|
if ((!gdk_event_get_button (event, &button) || button == 1) &&
|
||||||
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN &&
|
||||||
|
pointer_on_menu_widget (menu, x_root, y_root))
|
||||||
|
{
|
||||||
|
priv->drag_start_y = event->button.y_root;
|
||||||
|
priv->initial_drag_offset = priv->scroll_offset;
|
||||||
|
priv->drag_scroll_started = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
priv->drag_start_y = -1;
|
||||||
|
|
||||||
|
priv->drag_already_pressed = TRUE;
|
||||||
|
break;
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_BUTTON_RELEASE:
|
||||||
|
if (priv->drag_scroll_started)
|
||||||
|
{
|
||||||
|
priv->drag_scroll_started = FALSE;
|
||||||
|
priv->drag_start_y = -1;
|
||||||
|
priv->drag_already_pressed = FALSE;
|
||||||
|
retval = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_MOTION_NOTIFY:
|
||||||
|
if ((!gdk_event_get_state (event, &state) || (state & GDK_BUTTON1_MASK)
|
||||||
|
!= 0) &&
|
||||||
|
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
|
||||||
|
{
|
||||||
|
if (!priv->drag_already_pressed)
|
||||||
|
{
|
||||||
|
if (pointer_on_menu_widget (menu, x_root, y_root))
|
||||||
|
{
|
||||||
|
priv->drag_start_y = y_root;
|
||||||
|
priv->initial_drag_offset = priv->scroll_offset;
|
||||||
|
priv->drag_scroll_started = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
priv->drag_start_y = -1;
|
||||||
|
|
||||||
|
priv->drag_already_pressed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->drag_start_y < 0 && !priv->drag_scroll_started)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (priv->drag_scroll_started)
|
||||||
|
{
|
||||||
|
gint offset, view_height;
|
||||||
|
GtkBorder arrow_border;
|
||||||
|
gdouble y_diff;
|
||||||
|
|
||||||
|
y_diff = y_root - priv->drag_start_y;
|
||||||
|
offset = priv->initial_drag_offset - y_diff;
|
||||||
|
|
||||||
|
view_height = gdk_window_get_height (gtk_widget_get_window (widget));
|
||||||
|
get_arrows_border (menu, &arrow_border);
|
||||||
|
|
||||||
|
if (priv->upper_arrow_visible)
|
||||||
|
view_height -= arrow_border.top;
|
||||||
|
|
||||||
|
if (priv->lower_arrow_visible)
|
||||||
|
view_height -= arrow_border.bottom;
|
||||||
|
|
||||||
|
offset = CLAMP (offset, 0, priv->requested_height - view_height);
|
||||||
|
gtk_menu_scroll_to (menu, offset);
|
||||||
|
|
||||||
|
retval = TRUE;
|
||||||
|
}
|
||||||
|
else if (gtk_drag_check_threshold (widget,
|
||||||
|
0, priv->drag_start_y,
|
||||||
|
0, y_root))
|
||||||
|
{
|
||||||
|
priv->drag_scroll_started = TRUE;
|
||||||
|
gtk_menu_shell_deselect (GTK_MENU_SHELL (menu));
|
||||||
|
retval = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDK_ENTER_NOTIFY:
|
||||||
|
case GDK_LEAVE_NOTIFY:
|
||||||
|
if (priv->drag_scroll_started)
|
||||||
|
retval = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_menu_stop_navigating_submenu (GtkMenu *menu)
|
gtk_menu_stop_navigating_submenu (GtkMenu *menu)
|
||||||
{
|
{
|
||||||
@@ -4846,19 +4811,10 @@ static void
|
|||||||
gtk_menu_stop_scrolling (GtkMenu *menu)
|
gtk_menu_stop_scrolling (GtkMenu *menu)
|
||||||
{
|
{
|
||||||
GtkMenuPrivate *priv = menu->priv;
|
GtkMenuPrivate *priv = menu->priv;
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
gtk_menu_remove_scroll_timeout (menu);
|
gtk_menu_remove_scroll_timeout (menu);
|
||||||
|
priv->upper_arrow_prelight = FALSE;
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)),
|
priv->lower_arrow_prelight = FALSE;
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!touchscreen_mode)
|
|
||||||
{
|
|
||||||
priv->upper_arrow_prelight = FALSE;
|
|
||||||
priv->lower_arrow_prelight = FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -5664,7 +5620,6 @@ gtk_menu_real_move_scroll (GtkMenu *menu,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_menu_set_monitor:
|
* gtk_menu_set_monitor:
|
||||||
* @menu: a #GtkMenu
|
* @menu: a #GtkMenu
|
||||||
@@ -5741,11 +5696,13 @@ static void
|
|||||||
gtk_menu_grab_notify (GtkWidget *widget,
|
gtk_menu_grab_notify (GtkWidget *widget,
|
||||||
gboolean was_grabbed)
|
gboolean was_grabbed)
|
||||||
{
|
{
|
||||||
|
GtkMenu *menu;
|
||||||
GtkWidget *toplevel;
|
GtkWidget *toplevel;
|
||||||
GtkWindowGroup *group;
|
GtkWindowGroup *group;
|
||||||
GtkWidget *grab;
|
GtkWidget *grab;
|
||||||
GdkDevice *pointer;
|
GdkDevice *pointer;
|
||||||
|
|
||||||
|
menu = GTK_MENU (widget);
|
||||||
pointer = _gtk_menu_shell_get_grab_device (GTK_MENU_SHELL (widget));
|
pointer = _gtk_menu_shell_get_grab_device (GTK_MENU_SHELL (widget));
|
||||||
|
|
||||||
if (!pointer ||
|
if (!pointer ||
|
||||||
@@ -5762,6 +5719,8 @@ gtk_menu_grab_notify (GtkWidget *widget,
|
|||||||
|
|
||||||
if (GTK_MENU_SHELL (widget)->priv->active && !GTK_IS_MENU_SHELL (grab))
|
if (GTK_MENU_SHELL (widget)->priv->active && !GTK_IS_MENU_SHELL (grab))
|
||||||
gtk_menu_shell_cancel (GTK_MENU_SHELL (widget));
|
gtk_menu_shell_cancel (GTK_MENU_SHELL (widget));
|
||||||
|
|
||||||
|
menu->priv->drag_scroll_started = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1690,13 +1690,20 @@ static void
|
|||||||
gtk_real_menu_item_select (GtkMenuItem *menu_item)
|
gtk_real_menu_item_select (GtkMenuItem *menu_item)
|
||||||
{
|
{
|
||||||
GtkMenuItemPrivate *priv = menu_item->priv;
|
GtkMenuItemPrivate *priv = menu_item->priv;
|
||||||
gboolean touchscreen_mode;
|
GdkDevice *source_device = NULL;
|
||||||
|
GdkEvent *current_event;
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_item)),
|
current_event = gtk_get_current_event ();
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!touchscreen_mode && priv->submenu &&
|
if (current_event)
|
||||||
|
{
|
||||||
|
source_device = gdk_event_get_source_device (current_event);
|
||||||
|
gdk_event_free (current_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!source_device ||
|
||||||
|
gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN) &&
|
||||||
|
priv->submenu &&
|
||||||
(!gtk_widget_get_mapped (priv->submenu) ||
|
(!gtk_widget_get_mapped (priv->submenu) ||
|
||||||
GTK_MENU (priv->submenu)->priv->tearoff_active))
|
GTK_MENU (priv->submenu)->priv->tearoff_active))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ struct _GtkMenuPrivate
|
|||||||
guint seen_item_enter : 1;
|
guint seen_item_enter : 1;
|
||||||
guint ignore_button_release : 1;
|
guint ignore_button_release : 1;
|
||||||
guint no_toggle_size : 1;
|
guint no_toggle_size : 1;
|
||||||
|
guint drag_already_pressed : 1;
|
||||||
|
guint drag_scroll_started : 1;
|
||||||
|
|
||||||
/* info used for the table */
|
/* info used for the table */
|
||||||
guint *heights;
|
guint *heights;
|
||||||
@@ -126,6 +128,9 @@ struct _GtkMenuPrivate
|
|||||||
gint navigation_height;
|
gint navigation_height;
|
||||||
|
|
||||||
guint navigation_timeout;
|
guint navigation_timeout;
|
||||||
|
|
||||||
|
gdouble drag_start_y;
|
||||||
|
gint initial_drag_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -1084,13 +1084,11 @@ gtk_menu_shell_enter_notify (GtkWidget *widget,
|
|||||||
|
|
||||||
if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
|
if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
|
||||||
{
|
{
|
||||||
gboolean touchscreen_mode;
|
GdkDevice *source_device;
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (widget),
|
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (touchscreen_mode)
|
if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
|
||||||
_gtk_menu_item_popup_submenu (menu_item, TRUE);
|
_gtk_menu_item_popup_submenu (menu_item, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1612,45 +1610,19 @@ gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell,
|
|||||||
GtkMenuShellPrivate *priv = menu_shell->priv;
|
GtkMenuShellPrivate *priv = menu_shell->priv;
|
||||||
GtkMenuShell *parent_menu_shell = NULL;
|
GtkMenuShell *parent_menu_shell = NULL;
|
||||||
gboolean had_selection;
|
gboolean had_selection;
|
||||||
gboolean touchscreen_mode;
|
|
||||||
|
|
||||||
priv->in_unselectable_item = FALSE;
|
priv->in_unselectable_item = FALSE;
|
||||||
|
|
||||||
had_selection = priv->active_menu_item != NULL;
|
had_selection = priv->active_menu_item != NULL;
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen_mode,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (priv->parent_menu_shell)
|
if (priv->parent_menu_shell)
|
||||||
parent_menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
|
parent_menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
|
||||||
|
|
||||||
switch (direction)
|
switch (direction)
|
||||||
{
|
{
|
||||||
case GTK_MENU_DIR_PARENT:
|
case GTK_MENU_DIR_PARENT:
|
||||||
if (touchscreen_mode &&
|
if (parent_menu_shell)
|
||||||
priv->active_menu_item &&
|
|
||||||
GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu &&
|
|
||||||
gtk_widget_get_visible (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu))
|
|
||||||
{
|
{
|
||||||
/* if we are on a menu item that has an open submenu but the
|
|
||||||
* focus is not in that submenu (e.g. because it's empty or
|
|
||||||
* has only insensitive items), close that submenu instead of
|
|
||||||
* running into the code below which would close *this* menu.
|
|
||||||
*/
|
|
||||||
_gtk_menu_item_popdown_submenu (priv->active_menu_item);
|
|
||||||
_gtk_menu_shell_update_mnemonics (menu_shell);
|
|
||||||
}
|
|
||||||
else if (parent_menu_shell)
|
|
||||||
{
|
|
||||||
if (touchscreen_mode)
|
|
||||||
{
|
|
||||||
/* close menu when returning from submenu. */
|
|
||||||
_gtk_menu_item_popdown_submenu (GTK_MENU (menu_shell)->priv->parent_menu_item);
|
|
||||||
_gtk_menu_shell_update_mnemonics (parent_menu_shell);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement ==
|
if (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement ==
|
||||||
GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement)
|
GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement)
|
||||||
gtk_menu_shell_deselect (menu_shell);
|
gtk_menu_shell_deselect (menu_shell);
|
||||||
|
|||||||
358
gtk/gtkpaned.c
358
gtk/gtkpaned.c
@@ -36,6 +36,8 @@
|
|||||||
#include "gtktypebuiltins.h"
|
#include "gtktypebuiltins.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
|
#include "gtkdnd.h"
|
||||||
|
#include "gtkwidgetprivate.h"
|
||||||
#include "a11y/gtkpanedaccessible.h"
|
#include "a11y/gtkpanedaccessible.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,6 +100,17 @@ enum {
|
|||||||
CHILD2
|
CHILD2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GdkWindow *pane_window;
|
||||||
|
GdkDevice *device;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
gdouble x;
|
||||||
|
gdouble y;
|
||||||
|
GdkEvent *button_press_event;
|
||||||
|
guint press_consumed : 1;
|
||||||
|
} TouchInfo;
|
||||||
|
|
||||||
struct _GtkPanedPrivate
|
struct _GtkPanedPrivate
|
||||||
{
|
{
|
||||||
GtkPaned *first_paned;
|
GtkPaned *first_paned;
|
||||||
@@ -124,6 +137,8 @@ struct _GtkPanedPrivate
|
|||||||
|
|
||||||
guint32 grab_time;
|
guint32 grab_time;
|
||||||
|
|
||||||
|
GArray *touches;
|
||||||
|
|
||||||
guint handle_prelit : 1;
|
guint handle_prelit : 1;
|
||||||
guint in_drag : 1;
|
guint in_drag : 1;
|
||||||
guint in_recursion : 1;
|
guint in_recursion : 1;
|
||||||
@@ -255,6 +270,8 @@ static gboolean gtk_paned_toggle_handle_focus (GtkPaned *paned);
|
|||||||
static GType gtk_paned_child_type (GtkContainer *container);
|
static GType gtk_paned_child_type (GtkContainer *container);
|
||||||
static void gtk_paned_grab_notify (GtkWidget *widget,
|
static void gtk_paned_grab_notify (GtkWidget *widget,
|
||||||
gboolean was_grabbed);
|
gboolean was_grabbed);
|
||||||
|
static gboolean gtk_paned_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GtkPaned, gtk_paned, GTK_TYPE_CONTAINER,
|
G_DEFINE_TYPE_WITH_CODE (GtkPaned, gtk_paned, GTK_TYPE_CONTAINER,
|
||||||
@@ -708,6 +725,11 @@ gtk_paned_init (GtkPaned *paned)
|
|||||||
priv->handle_pos.y = -1;
|
priv->handle_pos.y = -1;
|
||||||
|
|
||||||
priv->drag_pos = -1;
|
priv->drag_pos = -1;
|
||||||
|
|
||||||
|
priv->touches = g_array_sized_new (FALSE, FALSE,
|
||||||
|
sizeof (TouchInfo), 2);
|
||||||
|
|
||||||
|
_gtk_widget_set_captured_event_handler (GTK_WIDGET (paned), gtk_paned_captured_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -863,9 +885,11 @@ static void
|
|||||||
gtk_paned_finalize (GObject *object)
|
gtk_paned_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GtkPaned *paned = GTK_PANED (object);
|
GtkPaned *paned = GTK_PANED (object);
|
||||||
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
|
||||||
gtk_paned_set_saved_focus (paned, NULL);
|
gtk_paned_set_saved_focus (paned, NULL);
|
||||||
gtk_paned_set_first_paned (paned, NULL);
|
gtk_paned_set_first_paned (paned, NULL);
|
||||||
|
g_array_free (priv->touches, TRUE);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_paned_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gtk_paned_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -1281,7 +1305,9 @@ gtk_paned_create_child_window (GtkPaned *paned,
|
|||||||
|
|
||||||
attributes.window_type = GDK_WINDOW_CHILD;
|
attributes.window_type = GDK_WINDOW_CHILD;
|
||||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||||
attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
|
attributes.event_mask = gtk_widget_get_events (widget) |
|
||||||
|
GDK_EXPOSURE_MASK | GDK_TOUCH_MASK;
|
||||||
|
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
@@ -1571,7 +1597,8 @@ gtk_paned_enter (GtkWidget *widget,
|
|||||||
GtkPaned *paned = GTK_PANED (widget);
|
GtkPaned *paned = GTK_PANED (widget);
|
||||||
GtkPanedPrivate *priv = paned->priv;
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
|
||||||
if (priv->in_drag)
|
if (priv->in_drag &&
|
||||||
|
priv->touches->len == 0)
|
||||||
update_drag (paned, event->x, event->y);
|
update_drag (paned, event->x, event->y);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1593,7 +1620,8 @@ gtk_paned_leave (GtkWidget *widget,
|
|||||||
GtkPaned *paned = GTK_PANED (widget);
|
GtkPaned *paned = GTK_PANED (widget);
|
||||||
GtkPanedPrivate *priv = paned->priv;
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
|
||||||
if (priv->in_drag)
|
if (priv->in_drag &&
|
||||||
|
priv->touches->len == 0)
|
||||||
update_drag (paned, event->x, event->y);
|
update_drag (paned, event->x, event->y);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1626,6 +1654,38 @@ gtk_paned_focus (GtkWidget *widget,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
start_drag (GtkPaned *paned,
|
||||||
|
GdkDevice *device,
|
||||||
|
int xpos,
|
||||||
|
int ypos,
|
||||||
|
guint time)
|
||||||
|
{
|
||||||
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
|
||||||
|
if (gdk_device_grab (device,
|
||||||
|
priv->handle,
|
||||||
|
GDK_OWNERSHIP_WINDOW, FALSE,
|
||||||
|
GDK_BUTTON1_MOTION_MASK
|
||||||
|
| GDK_BUTTON_RELEASE_MASK
|
||||||
|
| GDK_ENTER_NOTIFY_MASK
|
||||||
|
| GDK_LEAVE_NOTIFY_MASK
|
||||||
|
| GDK_TOUCH_MASK,
|
||||||
|
NULL, time) != GDK_GRAB_SUCCESS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
priv->in_drag = TRUE;
|
||||||
|
priv->grab_time = time;
|
||||||
|
priv->grab_device = device;
|
||||||
|
|
||||||
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
priv->drag_pos = xpos;
|
||||||
|
else
|
||||||
|
priv->drag_pos = ypos;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_paned_button_press (GtkWidget *widget,
|
gtk_paned_button_press (GtkWidget *widget,
|
||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
@@ -1636,27 +1696,10 @@ gtk_paned_button_press (GtkWidget *widget,
|
|||||||
if (!priv->in_drag &&
|
if (!priv->in_drag &&
|
||||||
(event->window == priv->handle) && (event->button == GDK_BUTTON_PRIMARY))
|
(event->window == priv->handle) && (event->button == GDK_BUTTON_PRIMARY))
|
||||||
{
|
{
|
||||||
/* We need a server grab here, not gtk_grab_add(), since
|
if (!start_drag (paned, event->device,
|
||||||
* we don't want to pass events on to the widget's children */
|
event->x, event->y, event->time))
|
||||||
if (gdk_device_grab (event->device,
|
|
||||||
priv->handle,
|
|
||||||
GDK_OWNERSHIP_WINDOW, FALSE,
|
|
||||||
GDK_BUTTON1_MOTION_MASK
|
|
||||||
| GDK_BUTTON_RELEASE_MASK
|
|
||||||
| GDK_ENTER_NOTIFY_MASK
|
|
||||||
| GDK_LEAVE_NOTIFY_MASK,
|
|
||||||
NULL, event->time) != GDK_GRAB_SUCCESS)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv->in_drag = TRUE;
|
|
||||||
priv->grab_time = event->time;
|
|
||||||
priv->grab_device = event->device;
|
|
||||||
|
|
||||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
priv->drag_pos = event->x;
|
|
||||||
else
|
|
||||||
priv->drag_pos = event->y;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1670,9 +1713,13 @@ gtk_paned_grab_broken (GtkWidget *widget,
|
|||||||
GtkPaned *paned = GTK_PANED (widget);
|
GtkPaned *paned = GTK_PANED (widget);
|
||||||
GtkPanedPrivate *priv = paned->priv;
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
|
||||||
priv->in_drag = FALSE;
|
if (event->grab_window != priv->handle &&
|
||||||
priv->drag_pos = -1;
|
gdk_event_get_device ((GdkEvent *) event) == priv->grab_device)
|
||||||
priv->position_set = TRUE;
|
{
|
||||||
|
priv->in_drag = FALSE;
|
||||||
|
priv->drag_pos = -1;
|
||||||
|
priv->position_set = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1687,7 +1734,7 @@ stop_drag (GtkPaned *paned)
|
|||||||
priv->position_set = TRUE;
|
priv->position_set = TRUE;
|
||||||
|
|
||||||
gdk_device_ungrab (priv->grab_device,
|
gdk_device_ungrab (priv->grab_device,
|
||||||
priv->grab_time);
|
gtk_get_current_event_time ());
|
||||||
priv->grab_device = NULL;
|
priv->grab_device = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1762,6 +1809,263 @@ gtk_paned_motion (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkWindow *
|
||||||
|
_gtk_paned_find_pane_window (GtkWidget *widget,
|
||||||
|
GdkEvent *event)
|
||||||
|
{
|
||||||
|
GtkPanedPrivate *priv = GTK_PANED (widget)->priv;
|
||||||
|
GtkWidget *event_widget;
|
||||||
|
|
||||||
|
event_widget = gtk_get_event_widget (event);
|
||||||
|
|
||||||
|
if (event_widget == widget)
|
||||||
|
{
|
||||||
|
if (event->any.window == priv->child1_window)
|
||||||
|
return priv->child1_window;
|
||||||
|
else if (event->any.window == priv->child2_window)
|
||||||
|
return priv->child2_window;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (event_widget == priv->child1 ||
|
||||||
|
gtk_widget_is_ancestor (event_widget, priv->child1))
|
||||||
|
return priv->child1_window;
|
||||||
|
else if (event_widget == priv->child2 ||
|
||||||
|
gtk_widget_is_ancestor (event_widget, priv->child2))
|
||||||
|
return priv->child2_window;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TouchInfo *
|
||||||
|
_gtk_paned_find_touch (GtkPaned *paned,
|
||||||
|
GdkDevice *device,
|
||||||
|
GdkEventSequence *sequence,
|
||||||
|
guint *index)
|
||||||
|
{
|
||||||
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
TouchInfo *info;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < priv->touches->len; i++)
|
||||||
|
{
|
||||||
|
info = &g_array_index (priv->touches, TouchInfo, i);
|
||||||
|
|
||||||
|
if (info->device == device && info->sequence == sequence)
|
||||||
|
{
|
||||||
|
if (index)
|
||||||
|
*index = i;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_paned_release_captured_event (GtkPaned *paned,
|
||||||
|
TouchInfo *touch,
|
||||||
|
gboolean emit)
|
||||||
|
{
|
||||||
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
GtkWidget *event_widget, *child;
|
||||||
|
|
||||||
|
if (!touch->button_press_event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
event_widget = gtk_get_event_widget (touch->button_press_event);
|
||||||
|
|
||||||
|
if (touch->pane_window == priv->child1_window)
|
||||||
|
child = priv->child1;
|
||||||
|
else if (touch->pane_window == priv->child2_window)
|
||||||
|
child = priv->child2;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (emit &&
|
||||||
|
!_gtk_propagate_captured_event (event_widget,
|
||||||
|
touch->button_press_event,
|
||||||
|
child))
|
||||||
|
gtk_propagate_event (event_widget, touch->button_press_event);
|
||||||
|
|
||||||
|
gdk_event_free (touch->button_press_event);
|
||||||
|
touch->button_press_event = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_paned_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event)
|
||||||
|
{
|
||||||
|
GtkPaned *paned = GTK_PANED (widget);
|
||||||
|
GtkPanedPrivate *priv = paned->priv;
|
||||||
|
GdkDevice *device, *source_device;
|
||||||
|
GdkWindow *pane_window;
|
||||||
|
TouchInfo new = { 0 }, *info;
|
||||||
|
GdkEventSequence *sequence;
|
||||||
|
guint index;
|
||||||
|
gdouble event_x, event_y;
|
||||||
|
gint x, y;
|
||||||
|
|
||||||
|
device = gdk_event_get_device (event);
|
||||||
|
source_device = gdk_event_get_source_device (event);
|
||||||
|
|
||||||
|
/* We possibly deal with both pointer and touch events,
|
||||||
|
* depending on the target window event mask, so assume
|
||||||
|
* touch ID = 0 for pointer events to ease handling.
|
||||||
|
*/
|
||||||
|
sequence = gdk_event_get_event_sequence (event);
|
||||||
|
|
||||||
|
gdk_event_get_coords (event, &event_x, &event_y);
|
||||||
|
|
||||||
|
if (!source_device ||
|
||||||
|
gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case GDK_BUTTON_PRESS:
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
if (priv->touches->len == 2)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pane_window = _gtk_paned_find_pane_window (widget, event);
|
||||||
|
gtk_widget_translate_coordinates (gtk_get_event_widget (event),
|
||||||
|
widget,
|
||||||
|
(gint)event_x, (gint)event_y,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
|
for (index = 0; index < priv->touches->len; index++)
|
||||||
|
{
|
||||||
|
info = &g_array_index (priv->touches, TouchInfo, index);
|
||||||
|
|
||||||
|
/* There was already a touch in this pane */
|
||||||
|
if (info->pane_window == pane_window)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
new.device = device;
|
||||||
|
new.sequence = sequence;
|
||||||
|
new.pane_window = pane_window;
|
||||||
|
new.x = x;
|
||||||
|
new.y = y;
|
||||||
|
g_array_append_val (priv->touches, new);
|
||||||
|
|
||||||
|
if (priv->touches->len == 1)
|
||||||
|
{
|
||||||
|
/* It's the first touch, store the event and set
|
||||||
|
* a timeout in order to release the event if no
|
||||||
|
* second touch happens timely.
|
||||||
|
*/
|
||||||
|
info = &g_array_index (priv->touches, TouchInfo, 0);
|
||||||
|
info->button_press_event = gdk_event_copy (event);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (priv->touches->len == 2)
|
||||||
|
{
|
||||||
|
GtkWidget *event_widget;
|
||||||
|
|
||||||
|
/* It's the second touch, release (don't emit) the
|
||||||
|
* held button/touch presses.
|
||||||
|
*/
|
||||||
|
for (index = 0; index < priv->touches->len; index++)
|
||||||
|
{
|
||||||
|
info = &g_array_index (priv->touches, TouchInfo, index);
|
||||||
|
gtk_paned_release_captured_event (paned, info, FALSE);
|
||||||
|
info->press_consumed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_widget = gtk_get_event_widget (event);
|
||||||
|
|
||||||
|
if (event_widget == widget)
|
||||||
|
{
|
||||||
|
if (pane_window == priv->child2_window)
|
||||||
|
{
|
||||||
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
event_x += priv->handle_pos.x + priv->handle_pos.width;
|
||||||
|
else
|
||||||
|
event_y += priv->handle_pos.y + priv->handle_pos.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gtk_widget_translate_coordinates (event_widget, widget,
|
||||||
|
(gint)event_x, (gint)event_y,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
|
start_drag (paned, device, x, y,
|
||||||
|
event->button.time);
|
||||||
|
|
||||||
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
priv->drag_pos = x - priv->handle_pos.x;
|
||||||
|
else
|
||||||
|
priv->drag_pos = y - priv->handle_pos.y;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GDK_BUTTON_RELEASE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
info = _gtk_paned_find_touch (GTK_PANED (widget), device, sequence, &index);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
gboolean press_consumed;
|
||||||
|
|
||||||
|
if (priv->touches->len == 2)
|
||||||
|
stop_drag (paned);
|
||||||
|
|
||||||
|
press_consumed = info->press_consumed;
|
||||||
|
|
||||||
|
/* Release the held button/touch press, if still queued */
|
||||||
|
gtk_paned_release_captured_event (paned, info, TRUE);
|
||||||
|
g_array_remove_index_fast (priv->touches, index);
|
||||||
|
|
||||||
|
if (press_consumed)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDK_MOTION_NOTIFY:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
info = _gtk_paned_find_touch (GTK_PANED (widget), device, sequence, &index);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
gtk_widget_translate_coordinates (gtk_get_event_widget (event),
|
||||||
|
widget,
|
||||||
|
event_x, event_y,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
|
/* If there is a single touch and this isn't a continuation
|
||||||
|
* from a previous successful 2-touch operation, check
|
||||||
|
* the threshold to let the child handle events.
|
||||||
|
*/
|
||||||
|
if (priv->touches->len == 1 &&
|
||||||
|
gtk_drag_check_threshold (widget, info->x, info->y, x, y))
|
||||||
|
{
|
||||||
|
gtk_paned_release_captured_event (paned, info, TRUE);
|
||||||
|
g_array_remove_index_fast (priv->touches, index);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (priv->touches->len == 2 && index == 1)
|
||||||
|
{
|
||||||
|
/* The device grab on priv->handle is in effect now,
|
||||||
|
* so the event coordinates are already relative to
|
||||||
|
* that window.
|
||||||
|
*/
|
||||||
|
update_drag (paned, event_x, event_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_paned_new:
|
* gtk_paned_new:
|
||||||
* @orientation: the paned's orientation.
|
* @orientation: the paned's orientation.
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ gboolean _gtk_translate_keyboard_accel_state (GdkKeymap *keymap,
|
|||||||
gint *level,
|
gint *level,
|
||||||
GdkModifierType *consumed_modifiers);
|
GdkModifierType *consumed_modifiers);
|
||||||
|
|
||||||
|
gboolean _gtk_propagate_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event,
|
||||||
|
GtkWidget *topmost);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_PRIVATE_H__ */
|
#endif /* __GTK_PRIVATE_H__ */
|
||||||
|
|||||||
@@ -2009,15 +2009,11 @@ gtk_range_draw (GtkWidget *widget,
|
|||||||
GtkStateFlags widget_state;
|
GtkStateFlags widget_state;
|
||||||
gint focus_line_width = 0;
|
gint focus_line_width = 0;
|
||||||
gint focus_padding = 0;
|
gint focus_padding = 0;
|
||||||
gboolean touchscreen;
|
|
||||||
gboolean draw_trough = TRUE;
|
gboolean draw_trough = TRUE;
|
||||||
gboolean draw_slider = TRUE;
|
gboolean draw_slider = TRUE;
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
context = gtk_widget_get_style_context (widget);
|
||||||
g_object_get (gtk_widget_get_settings (widget),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (GTK_IS_SCALE (widget) &&
|
if (GTK_IS_SCALE (widget) &&
|
||||||
gtk_adjustment_get_upper (priv->adjustment) == gtk_adjustment_get_lower (priv->adjustment))
|
gtk_adjustment_get_upper (priv->adjustment) == gtk_adjustment_get_lower (priv->adjustment))
|
||||||
@@ -2279,7 +2275,7 @@ gtk_range_draw (GtkWidget *widget,
|
|||||||
|
|
||||||
state &= ~(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE);
|
state &= ~(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE);
|
||||||
|
|
||||||
if (!touchscreen && priv->mouse_location == MOUSE_SLIDER && !(state & GTK_STATE_FLAG_INSENSITIVE))
|
if (priv->mouse_location == MOUSE_SLIDER && !(state & GTK_STATE_FLAG_INSENSITIVE))
|
||||||
state |= GTK_STATE_FLAG_PRELIGHT;
|
state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
|
|
||||||
if (priv->grab_location == MOUSE_SLIDER)
|
if (priv->grab_location == MOUSE_SLIDER)
|
||||||
@@ -2309,28 +2305,28 @@ gtk_range_draw (GtkWidget *widget,
|
|||||||
draw_stepper (range, STEPPER_A, cr,
|
draw_stepper (range, STEPPER_A, cr,
|
||||||
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
|
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
|
||||||
priv->grab_location == MOUSE_STEPPER_A,
|
priv->grab_location == MOUSE_STEPPER_A,
|
||||||
!touchscreen && priv->mouse_location == MOUSE_STEPPER_A,
|
priv->mouse_location == MOUSE_STEPPER_A,
|
||||||
widget_state);
|
widget_state);
|
||||||
|
|
||||||
if (priv->has_stepper_b)
|
if (priv->has_stepper_b)
|
||||||
draw_stepper (range, STEPPER_B, cr,
|
draw_stepper (range, STEPPER_B, cr,
|
||||||
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
|
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
|
||||||
priv->grab_location == MOUSE_STEPPER_B,
|
priv->grab_location == MOUSE_STEPPER_B,
|
||||||
!touchscreen && priv->mouse_location == MOUSE_STEPPER_B,
|
priv->mouse_location == MOUSE_STEPPER_B,
|
||||||
widget_state);
|
widget_state);
|
||||||
|
|
||||||
if (priv->has_stepper_c)
|
if (priv->has_stepper_c)
|
||||||
draw_stepper (range, STEPPER_C, cr,
|
draw_stepper (range, STEPPER_C, cr,
|
||||||
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
|
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
|
||||||
priv->grab_location == MOUSE_STEPPER_C,
|
priv->grab_location == MOUSE_STEPPER_C,
|
||||||
!touchscreen && priv->mouse_location == MOUSE_STEPPER_C,
|
priv->mouse_location == MOUSE_STEPPER_C,
|
||||||
widget_state);
|
widget_state);
|
||||||
|
|
||||||
if (priv->has_stepper_d)
|
if (priv->has_stepper_d)
|
||||||
draw_stepper (range, STEPPER_D, cr,
|
draw_stepper (range, STEPPER_D, cr,
|
||||||
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
|
priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
|
||||||
priv->grab_location == MOUSE_STEPPER_D,
|
priv->grab_location == MOUSE_STEPPER_D,
|
||||||
!touchscreen && priv->mouse_location == MOUSE_STEPPER_D,
|
priv->mouse_location == MOUSE_STEPPER_D,
|
||||||
widget_state);
|
widget_state);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -2528,7 +2524,8 @@ gtk_range_button_press (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
GtkRange *range = GTK_RANGE (widget);
|
GtkRange *range = GTK_RANGE (widget);
|
||||||
GtkRangePrivate *priv = range->priv;
|
GtkRangePrivate *priv = range->priv;
|
||||||
GdkDevice *device;
|
GdkDevice *device, *source_device;
|
||||||
|
GdkInputSource source;
|
||||||
|
|
||||||
if (!gtk_widget_has_focus (widget))
|
if (!gtk_widget_has_focus (widget))
|
||||||
gtk_widget_grab_focus (widget);
|
gtk_widget_grab_focus (widget);
|
||||||
@@ -2538,6 +2535,9 @@ gtk_range_button_press (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
device = gdk_event_get_device ((GdkEvent *) event);
|
device = gdk_event_get_device ((GdkEvent *) event);
|
||||||
|
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||||
|
source = gdk_device_get_source (source_device);
|
||||||
|
|
||||||
priv->mouse_x = event->x;
|
priv->mouse_x = event->x;
|
||||||
priv->mouse_y = event->y;
|
priv->mouse_y = event->y;
|
||||||
|
|
||||||
@@ -2554,23 +2554,24 @@ gtk_range_button_press (GtkWidget *widget,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->mouse_location == MOUSE_TROUGH &&
|
if (source != GDK_SOURCE_TOUCHSCREEN &&
|
||||||
|
priv->mouse_location == MOUSE_TROUGH &&
|
||||||
event->button == GDK_BUTTON_PRIMARY)
|
event->button == GDK_BUTTON_PRIMARY)
|
||||||
{
|
{
|
||||||
/* button 1 steps by page increment, as with button 2 on a stepper
|
/* button 1 steps by page increment, as with button 2 on a stepper
|
||||||
*/
|
*/
|
||||||
GtkScrollType scroll;
|
GtkScrollType scroll;
|
||||||
gdouble click_value;
|
gdouble click_value;
|
||||||
|
|
||||||
click_value = coord_to_value (range,
|
click_value = coord_to_value (range,
|
||||||
priv->orientation == GTK_ORIENTATION_VERTICAL ?
|
priv->orientation == GTK_ORIENTATION_VERTICAL ?
|
||||||
event->y : event->x);
|
event->y : event->x);
|
||||||
|
|
||||||
priv->trough_click_forward = click_value > gtk_adjustment_get_value (priv->adjustment);
|
priv->trough_click_forward = click_value > gtk_adjustment_get_value (priv->adjustment);
|
||||||
range_grab_add (range, device, MOUSE_TROUGH, event->button);
|
range_grab_add (range, device, MOUSE_TROUGH, event->button);
|
||||||
|
|
||||||
scroll = range_get_scroll_for_grab (range);
|
scroll = range_get_scroll_for_grab (range);
|
||||||
|
|
||||||
gtk_range_add_step_timer (range, scroll);
|
gtk_range_add_step_timer (range, scroll);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -2605,17 +2606,17 @@ gtk_range_button_press (GtkWidget *widget,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if ((priv->mouse_location == MOUSE_TROUGH &&
|
else if ((priv->mouse_location == MOUSE_TROUGH &&
|
||||||
event->button == GDK_BUTTON_MIDDLE) ||
|
(source == GDK_SOURCE_TOUCHSCREEN || event->button == GDK_BUTTON_MIDDLE)) ||
|
||||||
priv->mouse_location == MOUSE_SLIDER)
|
priv->mouse_location == MOUSE_SLIDER)
|
||||||
{
|
{
|
||||||
gboolean need_value_update = FALSE;
|
gboolean need_value_update = FALSE;
|
||||||
|
|
||||||
/* Any button can be used to drag the slider, but you can start
|
/* Any button can be used to drag the slider, but you can start
|
||||||
* dragging the slider with a trough click using button 2;
|
* dragging the slider with a trough click using button 2;
|
||||||
* On button 2 press, we warp the slider to mouse position,
|
* On button 2 press and touch devices, we warp the slider to
|
||||||
* then begin the slider drag.
|
* mouse position, then begin the slider drag.
|
||||||
*/
|
*/
|
||||||
if (event->button == GDK_BUTTON_MIDDLE)
|
if (event->button == GDK_BUTTON_MIDDLE || source == GDK_SOURCE_TOUCHSCREEN)
|
||||||
{
|
{
|
||||||
gdouble slider_low_value, slider_high_value, new_value;
|
gdouble slider_low_value, slider_high_value, new_value;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -117,6 +117,13 @@ void gtk_scrolled_window_set_min_content_width (GtkScrolledWindow *sc
|
|||||||
gint gtk_scrolled_window_get_min_content_height (GtkScrolledWindow *scrolled_window);
|
gint gtk_scrolled_window_get_min_content_height (GtkScrolledWindow *scrolled_window);
|
||||||
void gtk_scrolled_window_set_min_content_height (GtkScrolledWindow *scrolled_window,
|
void gtk_scrolled_window_set_min_content_height (GtkScrolledWindow *scrolled_window,
|
||||||
gint height);
|
gint height);
|
||||||
|
void gtk_scrolled_window_set_kinetic_scrolling (GtkScrolledWindow *scrolled_window,
|
||||||
|
gboolean kinetic_scrolling);
|
||||||
|
gboolean gtk_scrolled_window_get_kinetic_scrolling (GtkScrolledWindow *scrolled_window);
|
||||||
|
|
||||||
|
void gtk_scrolled_window_set_capture_button_press (GtkScrolledWindow *scrolled_window,
|
||||||
|
gboolean capture_button_press);
|
||||||
|
gboolean gtk_scrolled_window_get_capture_button_press (GtkScrolledWindow *scrolled_window);
|
||||||
|
|
||||||
gint _gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window);
|
gint _gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window);
|
||||||
|
|
||||||
|
|||||||
@@ -701,13 +701,16 @@ gtk_settings_class_init (GtkSettingsClass *class)
|
|||||||
* functionality.
|
* functionality.
|
||||||
*
|
*
|
||||||
* Since: 2.10
|
* Since: 2.10
|
||||||
|
*
|
||||||
|
* Deprecated: 3.4. Generally the behavior touchscreen input should be
|
||||||
|
* performed dynamically based on gdk_event_get_source_device().
|
||||||
*/
|
*/
|
||||||
result = settings_install_property_parser (class,
|
result = settings_install_property_parser (class,
|
||||||
g_param_spec_boolean ("gtk-touchscreen-mode",
|
g_param_spec_boolean ("gtk-touchscreen-mode",
|
||||||
P_("Enable Touchscreen Mode"),
|
P_("Enable Touchscreen Mode"),
|
||||||
P_("When TRUE, there are no motion notify events delivered on this screen"),
|
P_("When TRUE, there are no motion notify events delivered on this screen"),
|
||||||
FALSE,
|
FALSE,
|
||||||
GTK_PARAM_READWRITE),
|
GTK_PARAM_READWRITE | G_PARAM_DEPRECATED),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_assert (result == PROP_TOUCHSCREEN_MODE);
|
g_assert (result == PROP_TOUCHSCREEN_MODE);
|
||||||
|
|||||||
@@ -658,13 +658,9 @@ gtk_toggle_button_update_state (GtkButton *button)
|
|||||||
{
|
{
|
||||||
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
||||||
GtkToggleButtonPrivate *priv = toggle_button->priv;
|
GtkToggleButtonPrivate *priv = toggle_button->priv;
|
||||||
gboolean depressed, touchscreen;
|
gboolean depressed;
|
||||||
GtkStateFlags new_state = 0;
|
GtkStateFlags new_state = 0;
|
||||||
|
|
||||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (button)),
|
|
||||||
"gtk-touchscreen-mode", &touchscreen,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
new_state = gtk_widget_get_state_flags (GTK_WIDGET (button)) &
|
new_state = gtk_widget_get_state_flags (GTK_WIDGET (button)) &
|
||||||
~(GTK_STATE_FLAG_INCONSISTENT |
|
~(GTK_STATE_FLAG_INCONSISTENT |
|
||||||
GTK_STATE_FLAG_PRELIGHT |
|
GTK_STATE_FLAG_PRELIGHT |
|
||||||
@@ -680,7 +676,7 @@ gtk_toggle_button_update_state (GtkButton *button)
|
|||||||
else
|
else
|
||||||
depressed = priv->active;
|
depressed = priv->active;
|
||||||
|
|
||||||
if (!touchscreen && button->priv->in_button && (!button->priv->button_down || priv->draw_indicator))
|
if (button->priv->in_button && (!button->priv->button_down || priv->draw_indicator))
|
||||||
new_state |= GTK_STATE_FLAG_PRELIGHT;
|
new_state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
|
|
||||||
if (depressed)
|
if (depressed)
|
||||||
|
|||||||
@@ -1537,22 +1537,33 @@ _gtk_tooltip_hide (GtkWidget *widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
tooltips_enabled (GdkWindow *window)
|
tooltips_enabled (GdkEvent *event)
|
||||||
{
|
{
|
||||||
|
GdkDevice *source_device;
|
||||||
|
GdkInputSource source;
|
||||||
|
GdkWindow *window;
|
||||||
gboolean enabled;
|
gboolean enabled;
|
||||||
gboolean touchscreen;
|
|
||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
|
|
||||||
|
window = event->any.window;
|
||||||
|
source_device = gdk_event_get_source_device (event);
|
||||||
|
|
||||||
|
if (!source_device)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
source = gdk_device_get_source (source_device);
|
||||||
screen = gdk_window_get_screen (window);
|
screen = gdk_window_get_screen (window);
|
||||||
settings = gtk_settings_get_for_screen (screen);
|
settings = gtk_settings_get_for_screen (screen);
|
||||||
|
|
||||||
g_object_get (settings,
|
g_object_get (settings,
|
||||||
"gtk-touchscreen-mode", &touchscreen,
|
|
||||||
"gtk-enable-tooltips", &enabled,
|
"gtk-enable-tooltips", &enabled,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return (!touchscreen && enabled);
|
if (enabled && source != GDK_SOURCE_TOUCHSCREEN)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1564,7 +1575,7 @@ _gtk_tooltip_handle_event (GdkEvent *event)
|
|||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
GtkTooltip *current_tooltip;
|
GtkTooltip *current_tooltip;
|
||||||
|
|
||||||
if (!tooltips_enabled (event->any.window))
|
if (!tooltips_enabled (event))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Returns coordinates relative to has_tooltip_widget's allocation. */
|
/* Returns coordinates relative to has_tooltip_widget's allocation. */
|
||||||
|
|||||||
@@ -684,7 +684,7 @@ gtk_viewport_realize (GtkWidget *widget)
|
|||||||
event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
|
event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
|
||||||
/* We select on button_press_mask so that button 4-5 scrolls are trapped.
|
/* We select on button_press_mask so that button 4-5 scrolls are trapped.
|
||||||
*/
|
*/
|
||||||
attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK;
|
attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK | GDK_TOUCH_MASK;
|
||||||
|
|
||||||
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
|
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
|
||||||
|
|
||||||
|
|||||||
143
gtk/gtkwidget.c
143
gtk/gtkwidget.c
@@ -484,6 +484,7 @@ enum {
|
|||||||
QUERY_TOOLTIP,
|
QUERY_TOOLTIP,
|
||||||
DRAG_FAILED,
|
DRAG_FAILED,
|
||||||
STYLE_UPDATED,
|
STYLE_UPDATED,
|
||||||
|
TOUCH_EVENT,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -589,6 +590,8 @@ static gboolean gtk_widget_real_focus_in_event (GtkWidget *widget,
|
|||||||
GdkEventFocus *event);
|
GdkEventFocus *event);
|
||||||
static gboolean gtk_widget_real_focus_out_event (GtkWidget *widget,
|
static gboolean gtk_widget_real_focus_out_event (GtkWidget *widget,
|
||||||
GdkEventFocus *event);
|
GdkEventFocus *event);
|
||||||
|
static gboolean gtk_widget_real_touch_event (GtkWidget *widget,
|
||||||
|
GdkEventTouch *event);
|
||||||
static gboolean gtk_widget_real_focus (GtkWidget *widget,
|
static gboolean gtk_widget_real_focus (GtkWidget *widget,
|
||||||
GtkDirectionType direction);
|
GtkDirectionType direction);
|
||||||
static void gtk_widget_real_move_focus (GtkWidget *widget,
|
static void gtk_widget_real_move_focus (GtkWidget *widget,
|
||||||
@@ -705,6 +708,7 @@ static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
|
|||||||
GdkDevice *device,
|
GdkDevice *device,
|
||||||
gboolean recurse,
|
gboolean recurse,
|
||||||
gboolean enabled);
|
gboolean enabled);
|
||||||
|
static gboolean event_window_is_still_viewable (GdkEvent *event);
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
static gpointer gtk_widget_parent_class = NULL;
|
static gpointer gtk_widget_parent_class = NULL;
|
||||||
@@ -904,6 +908,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
klass->button_press_event = NULL;
|
klass->button_press_event = NULL;
|
||||||
klass->button_release_event = NULL;
|
klass->button_release_event = NULL;
|
||||||
klass->motion_notify_event = NULL;
|
klass->motion_notify_event = NULL;
|
||||||
|
klass->touch_event = gtk_widget_real_touch_event;
|
||||||
klass->delete_event = NULL;
|
klass->delete_event = NULL;
|
||||||
klass->destroy_event = NULL;
|
klass->destroy_event = NULL;
|
||||||
klass->key_press_event = gtk_widget_real_key_press_event;
|
klass->key_press_event = gtk_widget_real_key_press_event;
|
||||||
@@ -1888,6 +1893,15 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
G_TYPE_BOOLEAN, 1,
|
G_TYPE_BOOLEAN, 1,
|
||||||
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
|
widget_signals[TOUCH_EVENT] =
|
||||||
|
g_signal_new (I_("touch-event"),
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GtkWidgetClass, touch_event),
|
||||||
|
_gtk_boolean_handled_accumulator, NULL,
|
||||||
|
_gtk_marshal_BOOLEAN__BOXED,
|
||||||
|
G_TYPE_BOOLEAN, 1,
|
||||||
|
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
/**
|
/**
|
||||||
* GtkWidget::scroll-event:
|
* GtkWidget::scroll-event:
|
||||||
* @widget: the object which received the signal.
|
* @widget: the object which received the signal.
|
||||||
@@ -5832,6 +5846,76 @@ gtk_widget_real_focus_out_event (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_widget_real_touch_event (GtkWidget *widget,
|
||||||
|
GdkEventTouch *event)
|
||||||
|
{
|
||||||
|
GdkEvent *bevent;
|
||||||
|
gboolean return_val;
|
||||||
|
gint signum;
|
||||||
|
|
||||||
|
if (!event->emulating_pointer)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (event->type == GDK_TOUCH_BEGIN ||
|
||||||
|
event->type == GDK_TOUCH_END)
|
||||||
|
{
|
||||||
|
GdkEventType type;
|
||||||
|
|
||||||
|
if (event->type == GDK_TOUCH_BEGIN)
|
||||||
|
{
|
||||||
|
type = GDK_BUTTON_PRESS;
|
||||||
|
signum = BUTTON_PRESS_EVENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = GDK_BUTTON_RELEASE;
|
||||||
|
signum = BUTTON_RELEASE_EVENT;
|
||||||
|
}
|
||||||
|
bevent = gdk_event_new (type);
|
||||||
|
bevent->any.window = g_object_ref (event->window);
|
||||||
|
bevent->any.send_event = FALSE;
|
||||||
|
bevent->button.time = event->time;
|
||||||
|
bevent->button.state = event->state;
|
||||||
|
bevent->button.button = 1;
|
||||||
|
bevent->button.x_root = event->x_root;
|
||||||
|
bevent->button.y_root = event->y_root;
|
||||||
|
bevent->button.x = event->x;
|
||||||
|
bevent->button.y = event->y;
|
||||||
|
bevent->button.device = event->device;
|
||||||
|
bevent->button.axes = g_memdup (event->axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (event->device));
|
||||||
|
gdk_event_set_source_device (bevent, gdk_event_get_source_device ((GdkEvent*)event));
|
||||||
|
}
|
||||||
|
else if (event->type == GDK_TOUCH_UPDATE)
|
||||||
|
{
|
||||||
|
signum = MOTION_NOTIFY_EVENT;
|
||||||
|
bevent = gdk_event_new (GDK_MOTION_NOTIFY);
|
||||||
|
bevent->any.window = g_object_ref (event->window);
|
||||||
|
bevent->any.send_event = FALSE;
|
||||||
|
bevent->motion.time = event->time;
|
||||||
|
bevent->motion.state = event->state;
|
||||||
|
bevent->motion.x_root = event->x_root;
|
||||||
|
bevent->motion.y_root = event->y_root;
|
||||||
|
bevent->motion.x = event->x;
|
||||||
|
bevent->motion.y = event->y;
|
||||||
|
bevent->motion.device = event->device;
|
||||||
|
bevent->motion.is_hint = FALSE;
|
||||||
|
bevent->motion.axes = g_memdup (event->axes,
|
||||||
|
sizeof (gdouble) * gdk_device_get_n_axes (event->device));
|
||||||
|
gdk_event_set_source_device (bevent, gdk_event_get_source_device ((GdkEvent*)event));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_signal_emit (widget, widget_signals[signum], 0, bevent, &return_val);
|
||||||
|
|
||||||
|
gdk_event_free (bevent);
|
||||||
|
|
||||||
|
return return_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define WIDGET_REALIZED_FOR_EVENT(widget, event) \
|
#define WIDGET_REALIZED_FOR_EVENT(widget, event) \
|
||||||
(event->type == GDK_FOCUS_CHANGE || gtk_widget_get_realized(widget))
|
(event->type == GDK_FOCUS_CHANGE || gtk_widget_get_realized(widget))
|
||||||
|
|
||||||
@@ -5870,6 +5954,59 @@ gtk_widget_event (GtkWidget *widget,
|
|||||||
return gtk_widget_event_internal (widget, event);
|
return gtk_widget_event_internal (widget, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_widget_set_captured_event_handler (GtkWidget *widget,
|
||||||
|
GtkCapturedEventHandler callback)
|
||||||
|
{
|
||||||
|
g_object_set_data (G_OBJECT (widget), "captured-event-handler", callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_gtk_widget_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event)
|
||||||
|
{
|
||||||
|
gboolean return_val = FALSE;
|
||||||
|
GtkCapturedEventHandler handler;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
|
||||||
|
g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
|
||||||
|
|
||||||
|
if (event->type == GDK_EXPOSE)
|
||||||
|
{
|
||||||
|
g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
|
||||||
|
"the same effect, call gdk_window_invalidate_rect/region(), "
|
||||||
|
"followed by gdk_window_process_updates().");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event_window_is_still_viewable (event))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
handler = g_object_get_data (G_OBJECT (widget), "captured-event-handler");
|
||||||
|
if (!handler)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_object_ref (widget);
|
||||||
|
|
||||||
|
return_val = handler (widget, event);
|
||||||
|
return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
|
||||||
|
|
||||||
|
/* The widget that was originally to receive the event
|
||||||
|
* handles motion hints, but the capturing widget might
|
||||||
|
* not, so ensure we get further motion events.
|
||||||
|
*/
|
||||||
|
if (return_val &&
|
||||||
|
event->type == GDK_MOTION_NOTIFY &&
|
||||||
|
event->motion.is_hint &&
|
||||||
|
(gdk_window_get_events (event->any.window) &
|
||||||
|
GDK_POINTER_MOTION_HINT_MASK) != 0)
|
||||||
|
gdk_event_request_motions (&event->motion);
|
||||||
|
|
||||||
|
g_object_unref (widget);
|
||||||
|
|
||||||
|
return return_val;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns TRUE if a translation should be done */
|
/* Returns TRUE if a translation should be done */
|
||||||
gboolean
|
gboolean
|
||||||
_gtk_widget_get_translation_to_window (GtkWidget *widget,
|
_gtk_widget_get_translation_to_window (GtkWidget *widget,
|
||||||
@@ -6070,6 +6207,12 @@ gtk_widget_event_internal (GtkWidget *widget,
|
|||||||
case GDK_2BUTTON_PRESS:
|
case GDK_2BUTTON_PRESS:
|
||||||
case GDK_3BUTTON_PRESS:
|
case GDK_3BUTTON_PRESS:
|
||||||
signal_num = BUTTON_PRESS_EVENT;
|
signal_num = BUTTON_PRESS_EVENT;
|
||||||
|
break;
|
||||||
|
case GDK_TOUCH_BEGIN:
|
||||||
|
case GDK_TOUCH_UPDATE:
|
||||||
|
case GDK_TOUCH_END:
|
||||||
|
case GDK_TOUCH_CANCEL:
|
||||||
|
signal_num = TOUCH_EVENT;
|
||||||
break;
|
break;
|
||||||
case GDK_SCROLL:
|
case GDK_SCROLL:
|
||||||
signal_num = SCROLL_EVENT;
|
signal_num = SCROLL_EVENT;
|
||||||
|
|||||||
@@ -425,6 +425,9 @@ struct _GtkWidgetClass
|
|||||||
|
|
||||||
void (* style_updated) (GtkWidget *widget);
|
void (* style_updated) (GtkWidget *widget);
|
||||||
|
|
||||||
|
gboolean (* touch_event) (GtkWidget *widget,
|
||||||
|
GdkEventTouch *event);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
||||||
GtkWidgetClassPrivate *priv;
|
GtkWidgetClassPrivate *priv;
|
||||||
@@ -436,7 +439,6 @@ struct _GtkWidgetClass
|
|||||||
void (*_gtk_reserved5) (void);
|
void (*_gtk_reserved5) (void);
|
||||||
void (*_gtk_reserved6) (void);
|
void (*_gtk_reserved6) (void);
|
||||||
void (*_gtk_reserved7) (void);
|
void (*_gtk_reserved7) (void);
|
||||||
void (*_gtk_reserved8) (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkWidgetAuxInfo
|
struct _GtkWidgetAuxInfo
|
||||||
|
|||||||
@@ -167,6 +167,13 @@ GtkStyle * _gtk_widget_get_style (GtkWidget *widget);
|
|||||||
void _gtk_widget_set_style (GtkWidget *widget,
|
void _gtk_widget_set_style (GtkWidget *widget,
|
||||||
GtkStyle *style);
|
GtkStyle *style);
|
||||||
|
|
||||||
|
typedef gboolean (*GtkCapturedEventHandler) (GtkWidget *widget, GdkEvent *event);
|
||||||
|
|
||||||
|
void _gtk_widget_set_captured_event_handler (GtkWidget *widget,
|
||||||
|
GtkCapturedEventHandler handler);
|
||||||
|
|
||||||
|
gboolean _gtk_widget_captured_event (GtkWidget *widget,
|
||||||
|
GdkEvent *event);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
|||||||
testicontheme \
|
testicontheme \
|
||||||
testimage \
|
testimage \
|
||||||
testinput \
|
testinput \
|
||||||
|
testkineticscrolling \
|
||||||
testlockbutton \
|
testlockbutton \
|
||||||
testmenubars \
|
testmenubars \
|
||||||
testmountoperation \
|
testmountoperation \
|
||||||
@@ -181,6 +182,7 @@ testgrid_DEPENDENCIES = $(TEST_DEPS)
|
|||||||
testgtk_DEPENDENCIES = $(TEST_DEPS)
|
testgtk_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testinput_DEPENDENCIES = $(TEST_DEPS)
|
testinput_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testimage_DEPENDENCIES = $(TEST_DEPS)
|
testimage_DEPENDENCIES = $(TEST_DEPS)
|
||||||
|
testkineticscrolling_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testlockbutton_DEPENDENCIES = $(TEST_DEPS)
|
testlockbutton_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testmenubars_DEPENDENCIES = $(TEST_DEPS)
|
testmenubars_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testmountoperation_DEPENDENCIES = $(TEST_DEPS)
|
testmountoperation_DEPENDENCIES = $(TEST_DEPS)
|
||||||
@@ -280,6 +282,7 @@ testiconview_LDADD = $(LDADDS)
|
|||||||
testiconview_keynav_LDADD = $(LDADDS)
|
testiconview_keynav_LDADD = $(LDADDS)
|
||||||
testinput_LDADD = $(LDADDS)
|
testinput_LDADD = $(LDADDS)
|
||||||
testimage_LDADD = $(LDADDS)
|
testimage_LDADD = $(LDADDS)
|
||||||
|
testkineticscrolling_LDADD = $(LDADDS)
|
||||||
testlockbutton_LDADD = $(LDADDS)
|
testlockbutton_LDADD = $(LDADDS)
|
||||||
testmenubars_LDADD = $(LDADDS)
|
testmenubars_LDADD = $(LDADDS)
|
||||||
testmountoperation_LDADD = $(LDADDS)
|
testmountoperation_LDADD = $(LDADDS)
|
||||||
@@ -524,6 +527,8 @@ testpixbuf_save_SOURCES = testpixbuf-save.c
|
|||||||
|
|
||||||
testcolorchooser_SOURCES = testcolorchooser.c
|
testcolorchooser_SOURCES = testcolorchooser.c
|
||||||
|
|
||||||
|
testkineticscrolling_SOURCES = testkineticscrolling.c
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
gradient1.png \
|
gradient1.png \
|
||||||
prop-editor.h \
|
prop-editor.h \
|
||||||
|
|||||||
148
tests/testkineticscrolling.c
Normal file
148
tests/testkineticscrolling.c
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TARGET_GTK_TREE_MODEL_ROW
|
||||||
|
};
|
||||||
|
|
||||||
|
static GtkTargetEntry row_targets[] =
|
||||||
|
{
|
||||||
|
{ "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, TARGET_GTK_TREE_MODEL_ROW }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_button_clicked (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
g_print ("Button %d clicked\n", GPOINTER_TO_INT (data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kinetic_scrolling (void)
|
||||||
|
{
|
||||||
|
GtkWidget *window, *swindow, *grid;
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkWidget *button_grid, *button;
|
||||||
|
GtkWidget *treeview;
|
||||||
|
GtkCellRenderer *renderer;
|
||||||
|
GtkListStore *store;
|
||||||
|
GtkWidget *textview;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
|
||||||
|
g_signal_connect (window, "delete_event",
|
||||||
|
G_CALLBACK (gtk_main_quit), NULL);
|
||||||
|
|
||||||
|
grid = gtk_grid_new ();
|
||||||
|
|
||||||
|
label = gtk_label_new ("Non scrollable widget using viewport");
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||||
|
gtk_widget_set_hexpand (label, TRUE);
|
||||||
|
gtk_widget_show (label);
|
||||||
|
|
||||||
|
label = gtk_label_new ("Scrollable widget: TreeView");
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
|
||||||
|
gtk_widget_set_hexpand (label, TRUE);
|
||||||
|
gtk_widget_show (label);
|
||||||
|
|
||||||
|
label = gtk_label_new ("Scrollable widget: TextView");
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1);
|
||||||
|
gtk_widget_set_hexpand (label, TRUE);
|
||||||
|
gtk_widget_show (label);
|
||||||
|
|
||||||
|
button_grid = gtk_grid_new ();
|
||||||
|
for (i = 0; i < 80; i++)
|
||||||
|
{
|
||||||
|
gchar *label = g_strdup_printf ("Button number %d", i);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_label (label);
|
||||||
|
gtk_grid_attach (GTK_GRID (button_grid), button, 0, i, 1, 1);
|
||||||
|
gtk_widget_set_hexpand (button, TRUE);
|
||||||
|
gtk_widget_show (button);
|
||||||
|
g_signal_connect (button, "clicked",
|
||||||
|
G_CALLBACK (on_button_clicked),
|
||||||
|
GINT_TO_POINTER (i));
|
||||||
|
g_free (label);
|
||||||
|
}
|
||||||
|
|
||||||
|
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_kinetic_scrolling (GTK_SCROLLED_WINDOW (swindow), TRUE);
|
||||||
|
gtk_scrolled_window_set_capture_button_press (GTK_SCROLLED_WINDOW (swindow), TRUE);
|
||||||
|
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), button_grid);
|
||||||
|
gtk_widget_show (button_grid);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), swindow, 0, 1, 1, 1);
|
||||||
|
gtk_widget_show (swindow);
|
||||||
|
|
||||||
|
treeview = gtk_tree_view_new ();
|
||||||
|
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (treeview),
|
||||||
|
GDK_BUTTON1_MASK,
|
||||||
|
row_targets,
|
||||||
|
G_N_ELEMENTS (row_targets),
|
||||||
|
GDK_ACTION_MOVE | GDK_ACTION_COPY);
|
||||||
|
gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (treeview),
|
||||||
|
row_targets,
|
||||||
|
G_N_ELEMENTS (row_targets),
|
||||||
|
GDK_ACTION_MOVE | GDK_ACTION_COPY);
|
||||||
|
|
||||||
|
renderer = gtk_cell_renderer_text_new ();
|
||||||
|
g_object_set (renderer, "editable", TRUE, NULL);
|
||||||
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
|
||||||
|
0, "Title",
|
||||||
|
renderer,
|
||||||
|
"text", 0,
|
||||||
|
NULL);
|
||||||
|
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||||
|
for (i = 0; i < 80; i++)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *label = g_strdup_printf ("Row number %d", i);
|
||||||
|
|
||||||
|
gtk_list_store_append (store, &iter);
|
||||||
|
gtk_list_store_set (store, &iter, 0, label, -1);
|
||||||
|
g_free (label);
|
||||||
|
}
|
||||||
|
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
|
||||||
|
g_object_unref (store);
|
||||||
|
|
||||||
|
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_kinetic_scrolling (GTK_SCROLLED_WINDOW (swindow), TRUE);
|
||||||
|
gtk_scrolled_window_set_capture_button_press (GTK_SCROLLED_WINDOW (swindow), TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (swindow), treeview);
|
||||||
|
gtk_widget_show (treeview);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), swindow, 1, 1, 1, 1);
|
||||||
|
gtk_widget_set_hexpand (swindow, TRUE);
|
||||||
|
gtk_widget_set_vexpand (swindow, TRUE);
|
||||||
|
gtk_widget_show (swindow);
|
||||||
|
|
||||||
|
textview = gtk_text_view_new ();
|
||||||
|
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_kinetic_scrolling (GTK_SCROLLED_WINDOW (swindow), TRUE);
|
||||||
|
gtk_scrolled_window_set_capture_button_press (GTK_SCROLLED_WINDOW (swindow), TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (swindow), textview);
|
||||||
|
gtk_widget_show (textview);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), swindow, 2, 1, 1, 1);
|
||||||
|
gtk_widget_set_hexpand (swindow, TRUE);
|
||||||
|
gtk_widget_set_vexpand (swindow, TRUE);
|
||||||
|
gtk_widget_show (swindow);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||||
|
gtk_widget_show (grid);
|
||||||
|
|
||||||
|
gtk_widget_show (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
gtk_init (NULL, NULL);
|
||||||
|
|
||||||
|
kinetic_scrolling ();
|
||||||
|
|
||||||
|
gtk_main ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -53,6 +53,16 @@ content_height_changed (GtkSpinButton *spin_button,
|
|||||||
gtk_scrolled_window_set_min_content_height (swindow, (gint)value);
|
gtk_scrolled_window_set_min_content_height (swindow, (gint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kinetic_scrolling_changed (GtkToggleButton *toggle_button,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkScrolledWindow *swindow = data;
|
||||||
|
gboolean enabled = gtk_toggle_button_get_active (toggle_button);
|
||||||
|
|
||||||
|
gtk_scrolled_window_set_kinetic_scrolling (swindow, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
scrollable_policy (void)
|
scrollable_policy (void)
|
||||||
{
|
{
|
||||||
@@ -199,6 +209,13 @@ scrollable_policy (void)
|
|||||||
g_signal_connect (G_OBJECT (widget), "changed",
|
g_signal_connect (G_OBJECT (widget), "changed",
|
||||||
G_CALLBACK (label_flip_changed), label);
|
G_CALLBACK (label_flip_changed), label);
|
||||||
|
|
||||||
|
/* Add Kinetic scrolling control here */
|
||||||
|
widget = gtk_check_button_new_with_label ("Kinetic scrolling");
|
||||||
|
gtk_widget_show (widget);
|
||||||
|
gtk_box_pack_start (GTK_BOX (cntl), widget, TRUE, TRUE, 0);
|
||||||
|
g_signal_connect (G_OBJECT (widget), "toggled",
|
||||||
|
G_CALLBACK (kinetic_scrolling_changed), swindow);
|
||||||
|
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user