Compare commits
	
		
			5 Commits
		
	
	
		
			wip/carlos
			...
			gbsneto/cl
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 0c4fdb2d31 | ||
|   | 4504a313f7 | ||
|   | ed7fc825e1 | ||
|   | 43307c6b84 | ||
|   | b4d55325d7 | 
| @@ -52,6 +52,7 @@ | |||||||
| #include "compositor/compositor-private.h" | #include "compositor/compositor-private.h" | ||||||
| #include "core/display-private.h" | #include "core/display-private.h" | ||||||
| #include "meta/meta-cursor-tracker.h" | #include "meta/meta-cursor-tracker.h" | ||||||
|  | #include "meta/meta-x11-errors.h" | ||||||
| #include "meta/util.h" | #include "meta/util.h" | ||||||
|  |  | ||||||
| struct _MetaBackendX11Private | struct _MetaBackendX11Private | ||||||
| @@ -598,6 +599,10 @@ meta_backend_x11_warp_pointer (MetaBackend *backend, | |||||||
| { | { | ||||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); |   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); |   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||||
|  |   MetaDisplay *display = meta_get_display (); | ||||||
|  |  | ||||||
|  |   if (display) | ||||||
|  |     meta_x11_error_trap_push (display->x11_display); | ||||||
|  |  | ||||||
|   XIWarpPointer (priv->xdisplay, |   XIWarpPointer (priv->xdisplay, | ||||||
|                  META_VIRTUAL_CORE_POINTER_ID, |                  META_VIRTUAL_CORE_POINTER_ID, | ||||||
| @@ -605,6 +610,10 @@ meta_backend_x11_warp_pointer (MetaBackend *backend, | |||||||
|                  meta_backend_x11_get_xwindow (x11), |                  meta_backend_x11_get_xwindow (x11), | ||||||
|                  0, 0, 0, 0, |                  0, 0, 0, 0, | ||||||
|                  x, y); |                  x, y); | ||||||
|  |  | ||||||
|  |   if (display && | ||||||
|  |       meta_x11_error_trap_pop_with_return (display->x11_display) != Success) | ||||||
|  |     meta_verbose ("Failed to warp pointer\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static MetaLogicalMonitor * | static MetaLogicalMonitor * | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ | |||||||
| #include "meta/meta-x11-errors.h" | #include "meta/meta-x11-errors.h" | ||||||
| #include "meta/window.h" | #include "meta/window.h" | ||||||
| #include "x11/meta-x11-display-private.h" | #include "x11/meta-x11-display-private.h" | ||||||
|  | #include "x11/window-x11.h" | ||||||
|  |  | ||||||
| struct _MetaWindowActorX11 | struct _MetaWindowActorX11 | ||||||
| { | { | ||||||
| @@ -366,9 +367,12 @@ meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor, | |||||||
|   if (meta_window_actor_is_destroyed (actor)) |   if (meta_window_actor_is_destroyed (actor)) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|  |   g_assert (META_IS_WINDOW_X11 (window)); | ||||||
|  |  | ||||||
|   frame = g_slice_new0 (FrameData); |   frame = g_slice_new0 (FrameData); | ||||||
|   frame->frame_counter = -1; |   frame->frame_counter = -1; | ||||||
|   frame->sync_request_serial = window->sync_request_serial; |   frame->sync_request_serial = | ||||||
|  |     meta_window_x11_get_sync_request_serial (META_WINDOW_X11 (window)); | ||||||
|  |  | ||||||
|   actor_x11->frames = g_list_prepend (actor_x11->frames, frame); |   actor_x11->frames = g_list_prepend (actor_x11->frames, frame); | ||||||
|  |  | ||||||
| @@ -485,13 +489,14 @@ meta_window_actor_x11_constructed (GObject *object) | |||||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (object); |   MetaWindowActor *window_actor = META_WINDOW_ACTOR (object); | ||||||
|   MetaWindow *window = |   MetaWindow *window = | ||||||
|     meta_window_actor_get_meta_window (window_actor); |     meta_window_actor_get_meta_window (window_actor); | ||||||
|  |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|  |  | ||||||
|   G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->constructed (object); |   G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->constructed (object); | ||||||
|  |  | ||||||
|   /* If a window doesn't start off with updates frozen, we should |   /* If a window doesn't start off with updates frozen, we should | ||||||
|    * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. |    * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. | ||||||
|    */ |    */ | ||||||
|   if (window->extended_sync_request_counter && |   if (meta_window_x11_has_extended_sync_request_counter (window_x11) && | ||||||
|       !meta_window_updates_are_frozen (window)) |       !meta_window_updates_are_frozen (window)) | ||||||
|     meta_window_actor_queue_frame_drawn (window_actor, FALSE); |     meta_window_actor_queue_frame_drawn (window_actor, FALSE); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -403,9 +403,6 @@ struct _MetaWindow | |||||||
|   /* if TRUE we have a grab on the focus click buttons */ |   /* if TRUE we have a grab on the focus click buttons */ | ||||||
|   guint have_focus_click_grab : 1; |   guint have_focus_click_grab : 1; | ||||||
|  |  | ||||||
|   /* if TRUE, application is buggy and SYNC resizing is turned off */ |  | ||||||
|   guint disable_sync : 1; |  | ||||||
|  |  | ||||||
|   /* if TRUE, window is attached to its parent */ |   /* if TRUE, window is attached to its parent */ | ||||||
|   guint attached : 1; |   guint attached : 1; | ||||||
|  |  | ||||||
| @@ -431,21 +428,9 @@ struct _MetaWindow | |||||||
|   /* _NET_WM_WINDOW_OPACITY rescaled to 0xFF */ |   /* _NET_WM_WINDOW_OPACITY rescaled to 0xFF */ | ||||||
|   guint8 opacity; |   guint8 opacity; | ||||||
|  |  | ||||||
|   /* if TRUE, the we have the new form of sync request counter which |  | ||||||
|    * also handles application frames */ |  | ||||||
|   guint extended_sync_request_counter : 1; |  | ||||||
|  |  | ||||||
|   /* Note: can be NULL */ |   /* Note: can be NULL */ | ||||||
|   GSList *struts; |   GSList *struts; | ||||||
|  |  | ||||||
|   /* XSync update counter */ |  | ||||||
|   XSyncCounter sync_request_counter; |  | ||||||
|   gint64 sync_request_serial; |  | ||||||
|   gint64 sync_request_wait_serial; |  | ||||||
|   guint sync_request_timeout_id; |  | ||||||
|   /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ |  | ||||||
|   XSyncAlarm sync_request_alarm; |  | ||||||
|  |  | ||||||
|   /* Number of UnmapNotify that are caused by us, if |   /* Number of UnmapNotify that are caused by us, if | ||||||
|    * we get UnmapNotify with none pending then the client |    * we get UnmapNotify with none pending then the client | ||||||
|    * is withdrawing the window. |    * is withdrawing the window. | ||||||
| @@ -532,6 +517,8 @@ struct _MetaWindowClass | |||||||
|  |  | ||||||
|   void (*manage)                 (MetaWindow *window); |   void (*manage)                 (MetaWindow *window); | ||||||
|   void (*unmanage)               (MetaWindow *window); |   void (*unmanage)               (MetaWindow *window); | ||||||
|  |   void (*map)                    (MetaWindow *window); | ||||||
|  |   void (*unmap)                  (MetaWindow *window); | ||||||
|   void (*ping)                   (MetaWindow *window, |   void (*ping)                   (MetaWindow *window, | ||||||
|                                   guint32     serial); |                                   guint32     serial); | ||||||
|   void (*delete)                 (MetaWindow *window, |   void (*delete)                 (MetaWindow *window, | ||||||
| @@ -570,6 +557,7 @@ struct _MetaWindowClass | |||||||
|   gboolean (*is_stackable)        (MetaWindow *window); |   gboolean (*is_stackable)        (MetaWindow *window); | ||||||
|   gboolean (*can_ping)            (MetaWindow *window); |   gboolean (*can_ping)            (MetaWindow *window); | ||||||
|   gboolean (*are_updates_frozen)  (MetaWindow *window); |   gboolean (*are_updates_frozen)  (MetaWindow *window); | ||||||
|  |   gboolean (*has_pointer)         (MetaWindow *window); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* These differ from window->has_foo_func in that they consider | /* These differ from window->has_foo_func in that they consider | ||||||
|   | |||||||
| @@ -82,7 +82,6 @@ | |||||||
| #include "meta/group.h" | #include "meta/group.h" | ||||||
| #include "meta/meta-cursor-tracker.h" | #include "meta/meta-cursor-tracker.h" | ||||||
| #include "meta/meta-enum-types.h" | #include "meta/meta-enum-types.h" | ||||||
| #include "meta/meta-x11-errors.h" |  | ||||||
| #include "meta/prefs.h" | #include "meta/prefs.h" | ||||||
| #include "ui/ui.h" | #include "ui/ui.h" | ||||||
| #include "x11/meta-x11-display-private.h" | #include "x11/meta-x11-display-private.h" | ||||||
| @@ -799,6 +798,7 @@ client_window_should_be_mapped (MetaWindow *window) | |||||||
| static void | static void | ||||||
| sync_client_window_mapped (MetaWindow *window) | sync_client_window_mapped (MetaWindow *window) | ||||||
| { | { | ||||||
|  |   MetaWindowClass *window_class = META_WINDOW_GET_CLASS (window); | ||||||
|   gboolean should_be_mapped = client_window_should_be_mapped (window); |   gboolean should_be_mapped = client_window_should_be_mapped (window); | ||||||
|  |  | ||||||
|   g_return_if_fail (!window->override_redirect); |   g_return_if_fail (!window->override_redirect); | ||||||
| @@ -808,17 +808,15 @@ sync_client_window_mapped (MetaWindow *window) | |||||||
|  |  | ||||||
|   window->mapped = should_be_mapped; |   window->mapped = should_be_mapped; | ||||||
|  |  | ||||||
|   meta_x11_error_trap_push (window->display->x11_display); |  | ||||||
|   if (should_be_mapped) |   if (should_be_mapped) | ||||||
|     { |     { | ||||||
|       XMapWindow (window->display->x11_display->xdisplay, window->xwindow); |       window_class->map (window); | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       XUnmapWindow (window->display->x11_display->xdisplay, window->xwindow); |       window_class->unmap (window); | ||||||
|       window->unmaps_pending ++; |       window->unmaps_pending ++; | ||||||
|     } |     } | ||||||
|   meta_x11_error_trap_pop (window->display->x11_display); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static gboolean | static gboolean | ||||||
| @@ -999,11 +997,6 @@ _meta_window_shared_new (MetaDisplay         *display, | |||||||
|  |  | ||||||
|   window->workspace = NULL; |   window->workspace = NULL; | ||||||
|  |  | ||||||
|   window->sync_request_counter = None; |  | ||||||
|   window->sync_request_serial = 0; |  | ||||||
|   window->sync_request_timeout_id = 0; |  | ||||||
|   window->sync_request_alarm = None; |  | ||||||
|  |  | ||||||
|   meta_window_update_sandboxed_app_id (window); |   meta_window_update_sandboxed_app_id (window); | ||||||
|   meta_window_update_desc (window); |   meta_window_update_desc (window); | ||||||
|  |  | ||||||
| @@ -1083,7 +1076,6 @@ _meta_window_shared_new (MetaDisplay         *display, | |||||||
|   window->calc_placement = FALSE; |   window->calc_placement = FALSE; | ||||||
|   window->shaken_loose = FALSE; |   window->shaken_loose = FALSE; | ||||||
|   window->have_focus_click_grab = FALSE; |   window->have_focus_click_grab = FALSE; | ||||||
|   window->disable_sync = FALSE; |  | ||||||
|  |  | ||||||
|   window->unmaps_pending = 0; |   window->unmaps_pending = 0; | ||||||
|  |  | ||||||
| @@ -1528,12 +1520,6 @@ meta_window_unmanage (MetaWindow  *window, | |||||||
|       invalidate_work_areas (window); |       invalidate_work_areas (window); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (window->sync_request_timeout_id) |  | ||||||
|     { |  | ||||||
|       g_source_remove (window->sync_request_timeout_id); |  | ||||||
|       window->sync_request_timeout_id = 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   if (window->display->grab_window == window) |   if (window->display->grab_window == window) | ||||||
|     meta_display_end_grab_op (window->display, timestamp); |     meta_display_end_grab_op (window->display, timestamp); | ||||||
|  |  | ||||||
| @@ -5948,8 +5934,8 @@ check_moveresize_frequency (MetaWindow *window, | |||||||
|  |  | ||||||
|   /* If we are throttling via _NET_WM_SYNC_REQUEST, we don't need |   /* If we are throttling via _NET_WM_SYNC_REQUEST, we don't need | ||||||
|    * an artificial timeout-based throttled */ |    * an artificial timeout-based throttled */ | ||||||
|   if (!window->disable_sync && |   if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && | ||||||
|       window->sync_request_alarm != None) |       meta_window_x11_has_sync_request_alarm (META_WINDOW_X11 (window))) | ||||||
|     return TRUE; |     return TRUE; | ||||||
|  |  | ||||||
|   elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_time); |   elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_time); | ||||||
| @@ -6311,7 +6297,8 @@ update_resize (MetaWindow *window, | |||||||
|    * resize the window when the window responds, or when we time |    * resize the window when the window responds, or when we time | ||||||
|    * the response out. |    * the response out. | ||||||
|    */ |    */ | ||||||
|   if (window->sync_request_timeout_id != 0) |   if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && | ||||||
|  |       meta_window_x11_is_sync_request_scheduled (META_WINDOW_X11 (window))) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   if (!check_moveresize_frequency (window, &remaining) && !force) |   if (!check_moveresize_frequency (window, &remaining) && !force) | ||||||
| @@ -6823,7 +6810,7 @@ meta_window_is_ancestor_of_transient (MetaWindow *window, | |||||||
| /* Warp pointer to location appropriate for grab, | /* Warp pointer to location appropriate for grab, | ||||||
|  * return root coordinates where pointer ended up. |  * return root coordinates where pointer ended up. | ||||||
|  */ |  */ | ||||||
| static gboolean | static void | ||||||
| warp_grab_pointer (MetaWindow          *window, | warp_grab_pointer (MetaWindow          *window, | ||||||
|                    MetaGrabOp           grab_op, |                    MetaGrabOp           grab_op, | ||||||
|                    int                 *x, |                    int                 *x, | ||||||
| @@ -6864,8 +6851,6 @@ warp_grab_pointer (MetaWindow          *window, | |||||||
|   *x = CLAMP (*x, 0, display_rect.width - 1); |   *x = CLAMP (*x, 0, display_rect.width - 1); | ||||||
|   *y = CLAMP (*y, 0, display_rect.height - 1); |   *y = CLAMP (*y, 0, display_rect.height - 1); | ||||||
|  |  | ||||||
|   meta_x11_error_trap_push (display->x11_display); |  | ||||||
|  |  | ||||||
|   meta_topic (META_DEBUG_WINDOW_OPS, |   meta_topic (META_DEBUG_WINDOW_OPS, | ||||||
|               "Warping pointer to %d,%d with window at %d,%d\n", |               "Warping pointer to %d,%d with window at %d,%d\n", | ||||||
|               *x, *y, rect.x, rect.y); |               *x, *y, rect.x, rect.y); | ||||||
| @@ -6881,19 +6866,8 @@ warp_grab_pointer (MetaWindow          *window, | |||||||
|   meta_window_get_frame_rect (window, |   meta_window_get_frame_rect (window, | ||||||
|                               &display->grab_anchor_window_pos); |                               &display->grab_anchor_window_pos); | ||||||
|  |  | ||||||
|   { |  | ||||||
|     MetaBackend *backend = meta_get_backend (); |  | ||||||
|     meta_backend_warp_pointer (backend, *x, *y); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (meta_x11_error_trap_pop_with_return (display->x11_display) != Success) |   meta_backend_warp_pointer (meta_get_backend (), *x, *y); | ||||||
|     { |  | ||||||
|       meta_verbose ("Failed to warp pointer for window %s\n", |  | ||||||
|                     window->desc); |  | ||||||
|       return FALSE; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   return TRUE; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -8118,51 +8092,10 @@ mouse_mode_focus (MetaWindow  *window, | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static gboolean |  | ||||||
| window_has_pointer_wayland (MetaWindow *window) |  | ||||||
| { |  | ||||||
|   ClutterDeviceManager *dm; |  | ||||||
|   ClutterInputDevice *dev; |  | ||||||
|   ClutterActor *pointer_actor, *window_actor; |  | ||||||
|  |  | ||||||
|   dm = clutter_device_manager_get_default (); |  | ||||||
|   dev = clutter_device_manager_get_core_device (dm, CLUTTER_POINTER_DEVICE); |  | ||||||
|   pointer_actor = clutter_input_device_get_pointer_actor (dev); |  | ||||||
|   window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); |  | ||||||
|  |  | ||||||
|   return pointer_actor && clutter_actor_contains (window_actor, pointer_actor); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static gboolean |  | ||||||
| window_has_pointer_x11 (MetaWindow *window) |  | ||||||
| { |  | ||||||
|   MetaX11Display *x11_display = window->display->x11_display; |  | ||||||
|   Window root, child; |  | ||||||
|   double root_x, root_y, x, y; |  | ||||||
|   XIButtonState buttons; |  | ||||||
|   XIModifierState mods; |  | ||||||
|   XIGroupState group; |  | ||||||
|  |  | ||||||
|   meta_x11_error_trap_push (x11_display); |  | ||||||
|   XIQueryPointer (x11_display->xdisplay, |  | ||||||
|                   META_VIRTUAL_CORE_POINTER_ID, |  | ||||||
|                   x11_display->xroot, |  | ||||||
|                   &root, &child, |  | ||||||
|                   &root_x, &root_y, &x, &y, |  | ||||||
|                   &buttons, &mods, &group); |  | ||||||
|   meta_x11_error_trap_pop (x11_display); |  | ||||||
|   free (buttons.mask); |  | ||||||
|  |  | ||||||
|   return meta_x11_display_lookup_x_window (x11_display, child) == window; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| gboolean | gboolean | ||||||
| meta_window_has_pointer (MetaWindow *window) | meta_window_has_pointer (MetaWindow *window) | ||||||
| { | { | ||||||
|   if (meta_is_wayland_compositor ()) |   return META_WINDOW_GET_CLASS (window)->has_pointer (window); | ||||||
|     return window_has_pointer_wayland (window); |  | ||||||
|   else |  | ||||||
|     return window_has_pointer_x11 (window); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static gboolean | static gboolean | ||||||
|   | |||||||
| @@ -111,6 +111,16 @@ meta_window_wayland_unmanage (MetaWindow *window) | |||||||
|   meta_display_unregister_wayland_window (window->display, window); |   meta_display_unregister_wayland_window (window->display, window); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | meta_window_wayland_map (MetaWindow *window) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | meta_window_wayland_unmap (MetaWindow *window) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| meta_window_wayland_ping (MetaWindow *window, | meta_window_wayland_ping (MetaWindow *window, | ||||||
|                           guint32     serial) |                           guint32     serial) | ||||||
| @@ -611,6 +621,21 @@ meta_window_wayland_are_updates_frozen (MetaWindow *window) | |||||||
|   return !wl_window->has_been_shown; |   return !wl_window->has_been_shown; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static gboolean | ||||||
|  | meta_window_wayland_has_pointer (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   ClutterDeviceManager *dm; | ||||||
|  |   ClutterInputDevice *dev; | ||||||
|  |   ClutterActor *pointer_actor, *window_actor; | ||||||
|  |  | ||||||
|  |   dm = clutter_device_manager_get_default (); | ||||||
|  |   dev = clutter_device_manager_get_core_device (dm, CLUTTER_POINTER_DEVICE); | ||||||
|  |   pointer_actor = clutter_input_device_get_pointer_actor (dev); | ||||||
|  |   window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); | ||||||
|  |  | ||||||
|  |   return pointer_actor && clutter_actor_contains (window_actor, pointer_actor); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| meta_window_wayland_class_init (MetaWindowWaylandClass *klass) | meta_window_wayland_class_init (MetaWindowWaylandClass *klass) | ||||||
| { | { | ||||||
| @@ -618,6 +643,8 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) | |||||||
|  |  | ||||||
|   window_class->manage = meta_window_wayland_manage; |   window_class->manage = meta_window_wayland_manage; | ||||||
|   window_class->unmanage = meta_window_wayland_unmanage; |   window_class->unmanage = meta_window_wayland_unmanage; | ||||||
|  |   window_class->map = meta_window_wayland_map; | ||||||
|  |   window_class->unmap = meta_window_wayland_unmap; | ||||||
|   window_class->ping = meta_window_wayland_ping; |   window_class->ping = meta_window_wayland_ping; | ||||||
|   window_class->delete = meta_window_wayland_delete; |   window_class->delete = meta_window_wayland_delete; | ||||||
|   window_class->kill = meta_window_wayland_kill; |   window_class->kill = meta_window_wayland_kill; | ||||||
| @@ -634,6 +661,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) | |||||||
|   window_class->is_stackable = meta_window_wayland_is_stackable; |   window_class->is_stackable = meta_window_wayland_is_stackable; | ||||||
|   window_class->can_ping = meta_window_wayland_can_ping; |   window_class->can_ping = meta_window_wayland_can_ping; | ||||||
|   window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen; |   window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen; | ||||||
|  |   window_class->has_pointer = meta_window_wayland_has_pointer; | ||||||
| } | } | ||||||
|  |  | ||||||
| MetaWindow * | MetaWindow * | ||||||
|   | |||||||
| @@ -71,6 +71,21 @@ meta_window_xwayland_shortcuts_inhibited (MetaWindow         *window, | |||||||
|   return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source); |   return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static gboolean | ||||||
|  | meta_window_xwayland_has_pointer (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   ClutterDeviceManager *dm; | ||||||
|  |   ClutterInputDevice *dev; | ||||||
|  |   ClutterActor *pointer_actor, *window_actor; | ||||||
|  |  | ||||||
|  |   dm = clutter_device_manager_get_default (); | ||||||
|  |   dev = clutter_device_manager_get_core_device (dm, CLUTTER_POINTER_DEVICE); | ||||||
|  |   pointer_actor = clutter_input_device_get_pointer_actor (dev); | ||||||
|  |   window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); | ||||||
|  |  | ||||||
|  |   return pointer_actor && clutter_actor_contains (window_actor, pointer_actor); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| meta_window_xwayland_get_property (GObject    *object, | meta_window_xwayland_get_property (GObject    *object, | ||||||
|                                    guint       prop_id, |                                    guint       prop_id, | ||||||
| @@ -117,6 +132,7 @@ meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) | |||||||
|  |  | ||||||
|   window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts; |   window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts; | ||||||
|   window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited; |   window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited; | ||||||
|  |   window_class->has_pointer = meta_window_xwayland_has_pointer; | ||||||
|  |  | ||||||
|   gobject_class->get_property = meta_window_xwayland_get_property; |   gobject_class->get_property = meta_window_xwayland_get_property; | ||||||
|   gobject_class->set_property = meta_window_xwayland_set_property; |   gobject_class->set_property = meta_window_xwayland_set_property; | ||||||
|   | |||||||
| @@ -1068,34 +1068,9 @@ reload_update_counter (MetaWindow    *window, | |||||||
|                        MetaPropValue *value, |                        MetaPropValue *value, | ||||||
|                        gboolean       initial) |                        gboolean       initial) | ||||||
| { | { | ||||||
|   if (value->type != META_PROP_VALUE_INVALID) |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|     { |  | ||||||
|       meta_window_x11_destroy_sync_request_alarm (window); |  | ||||||
|       window->sync_request_counter = None; |  | ||||||
|  |  | ||||||
|       if (value->v.xcounter_list.n_counters == 0) |   meta_window_x11_setup_sync_request_counter (window_x11, value); | ||||||
|         { |  | ||||||
|           meta_warning ("_NET_WM_SYNC_REQUEST_COUNTER is empty\n"); |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       if (value->v.xcounter_list.n_counters == 1) |  | ||||||
|         { |  | ||||||
|           window->sync_request_counter = value->v.xcounter_list.counters[0]; |  | ||||||
|           window->extended_sync_request_counter = FALSE; |  | ||||||
|         } |  | ||||||
|       else |  | ||||||
|         { |  | ||||||
|           window->sync_request_counter = value->v.xcounter_list.counters[1]; |  | ||||||
|           window->extended_sync_request_counter = TRUE; |  | ||||||
|         } |  | ||||||
|       meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx (extended=%s)\n", |  | ||||||
|                     window->sync_request_counter, |  | ||||||
|                     window->extended_sync_request_counter ? "true" : "false"); |  | ||||||
|  |  | ||||||
|       if (window->extended_sync_request_counter) |  | ||||||
|         meta_window_x11_create_sync_request_alarm (window); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #define FLAG_TOGGLED_ON(old,new,flag) \ | #define FLAG_TOGGLED_ON(old,new,flag) \ | ||||||
|   | |||||||
| @@ -25,6 +25,8 @@ | |||||||
|  |  | ||||||
| #include "core/window-private.h" | #include "core/window-private.h" | ||||||
| #include "x11/iconcache.h" | #include "x11/iconcache.h" | ||||||
|  | #include "x11/window-x11.h" | ||||||
|  | #include "x11/xprops.h" | ||||||
|  |  | ||||||
| G_BEGIN_DECLS | G_BEGIN_DECLS | ||||||
|  |  | ||||||
| @@ -72,8 +74,28 @@ struct _MetaWindowX11Private | |||||||
|   MetaIconCache icon_cache; |   MetaIconCache icon_cache; | ||||||
|   Pixmap wm_hints_pixmap; |   Pixmap wm_hints_pixmap; | ||||||
|   Pixmap wm_hints_mask; |   Pixmap wm_hints_mask; | ||||||
|  |  | ||||||
|  |   /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ | ||||||
|  |   XSyncAlarm sync_request_alarm; | ||||||
|  |  | ||||||
|  |   /* XSync update counter */ | ||||||
|  |   XSyncCounter sync_request_counter; | ||||||
|  |  | ||||||
|  |   int64_t sync_request_serial; | ||||||
|  |   int64_t sync_request_wait_serial; | ||||||
|  |   guint sync_request_timeout_id; | ||||||
|  |  | ||||||
|  |   /* if TRUE, application is buggy and SYNC resizing is turned off */ | ||||||
|  |   gboolean disable_sync; | ||||||
|  |  | ||||||
|  |   /* if TRUE, the we have the new form of sync request counter which | ||||||
|  |    * also handles application frames */ | ||||||
|  |   gboolean extended_sync_request_counter; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | void meta_window_x11_setup_sync_request_counter (MetaWindowX11 *window_x11, | ||||||
|  |                                                  MetaPropValue *value); | ||||||
|  |  | ||||||
| G_END_DECLS | G_END_DECLS | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -510,6 +510,97 @@ meta_window_apply_session_info (MetaWindow *window, | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | meta_window_x11_create_sync_request_alarm (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |   MetaX11Display *x11_display = window->display->x11_display; | ||||||
|  |   XSyncAlarmAttributes values; | ||||||
|  |   XSyncValue init; | ||||||
|  |  | ||||||
|  |   if (priv->sync_request_counter == None || | ||||||
|  |       priv->sync_request_alarm != None) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   meta_x11_error_trap_push (x11_display); | ||||||
|  |  | ||||||
|  |   /* In the new (extended style), the counter value is initialized by | ||||||
|  |    * the client before mapping the window. In the old style, we're | ||||||
|  |    * responsible for setting the initial value of the counter. | ||||||
|  |    */ | ||||||
|  |   if (priv->extended_sync_request_counter) | ||||||
|  |     { | ||||||
|  |       if (!XSyncQueryCounter(x11_display->xdisplay, | ||||||
|  |                              priv->sync_request_counter, | ||||||
|  |                              &init)) | ||||||
|  |         { | ||||||
|  |           meta_x11_error_trap_pop_with_return (x11_display); | ||||||
|  |           priv->sync_request_counter = None; | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       priv->sync_request_serial = | ||||||
|  |         XSyncValueLow32 (init) + ((gint64)XSyncValueHigh32 (init) << 32); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       XSyncIntToValue (&init, 0); | ||||||
|  |       XSyncSetCounter (x11_display->xdisplay, | ||||||
|  |                        priv->sync_request_counter, init); | ||||||
|  |       priv->sync_request_serial = 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   values.trigger.counter = priv->sync_request_counter; | ||||||
|  |   values.trigger.test_type = XSyncPositiveComparison; | ||||||
|  |  | ||||||
|  |   /* Initialize to one greater than the current value */ | ||||||
|  |   values.trigger.value_type = XSyncRelative; | ||||||
|  |   XSyncIntToValue (&values.trigger.wait_value, 1); | ||||||
|  |  | ||||||
|  |   /* After triggering, increment test_value by this until | ||||||
|  |    * until the test condition is false */ | ||||||
|  |   XSyncIntToValue (&values.delta, 1); | ||||||
|  |  | ||||||
|  |   /* we want events (on by default anyway) */ | ||||||
|  |   values.events = True; | ||||||
|  |  | ||||||
|  |   priv->sync_request_alarm = XSyncCreateAlarm (x11_display->xdisplay, | ||||||
|  |                                                XSyncCACounter | | ||||||
|  |                                                XSyncCAValueType | | ||||||
|  |                                                XSyncCAValue | | ||||||
|  |                                                XSyncCATestType | | ||||||
|  |                                                XSyncCADelta | | ||||||
|  |                                                XSyncCAEvents, | ||||||
|  |                                                &values); | ||||||
|  |  | ||||||
|  |   if (meta_x11_error_trap_pop_with_return (x11_display) == Success) | ||||||
|  |     meta_x11_display_register_sync_alarm (x11_display, &priv->sync_request_alarm, window); | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       priv->sync_request_alarm = None; | ||||||
|  |       priv->sync_request_counter = None; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | meta_window_x11_destroy_sync_request_alarm (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (META_WINDOW_X11 (window)); | ||||||
|  |   MetaX11Display *x11_display = window->display->x11_display; | ||||||
|  |  | ||||||
|  |   if (priv->sync_request_alarm != None) | ||||||
|  |     { | ||||||
|  |       /* Has to be unregistered _before_ clearing the structure field */ | ||||||
|  |       meta_x11_display_unregister_sync_alarm (x11_display, priv->sync_request_alarm); | ||||||
|  |       XSyncDestroyAlarm (x11_display->xdisplay, | ||||||
|  |                          priv->sync_request_alarm); | ||||||
|  |       priv->sync_request_alarm = None; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| meta_window_x11_manage (MetaWindow *window) | meta_window_x11_manage (MetaWindow *window) | ||||||
| { | { | ||||||
| @@ -588,6 +679,12 @@ meta_window_x11_unmanage (MetaWindow *window) | |||||||
|   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|   MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); |   MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); | ||||||
|  |  | ||||||
|  |   if (priv->sync_request_timeout_id) | ||||||
|  |     { | ||||||
|  |       g_source_remove (priv->sync_request_timeout_id); | ||||||
|  |       priv->sync_request_timeout_id = 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   meta_x11_error_trap_push (x11_display); |   meta_x11_error_trap_push (x11_display); | ||||||
|  |  | ||||||
|   meta_window_x11_destroy_sync_request_alarm (window); |   meta_window_x11_destroy_sync_request_alarm (window); | ||||||
| @@ -703,6 +800,28 @@ meta_window_x11_can_ping (MetaWindow *window) | |||||||
|   return priv->wm_ping; |   return priv->wm_ping; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | meta_window_x11_map (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   meta_x11_error_trap_push (window->display->x11_display); | ||||||
|  |  | ||||||
|  |   XMapWindow (window->display->x11_display->xdisplay, | ||||||
|  |               window->xwindow); | ||||||
|  |  | ||||||
|  |   meta_x11_error_trap_pop (window->display->x11_display); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | meta_window_x11_unmap (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   meta_x11_error_trap_push (window->display->x11_display); | ||||||
|  |  | ||||||
|  |   XUnmapWindow (window->display->x11_display->xdisplay, | ||||||
|  |                 window->xwindow); | ||||||
|  |  | ||||||
|  |   meta_x11_error_trap_pop (window->display->x11_display); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| meta_window_x11_ping (MetaWindow *window, | meta_window_x11_ping (MetaWindow *window, | ||||||
|                       guint32     serial) |                       guint32     serial) | ||||||
| @@ -895,7 +1014,7 @@ meta_window_x11_grab_op_began (MetaWindow *window, | |||||||
|  |  | ||||||
|   if (meta_grab_op_is_resizing (op)) |   if (meta_grab_op_is_resizing (op)) | ||||||
|     { |     { | ||||||
|       if (window->sync_request_counter != None) |       if (priv->sync_request_counter != None) | ||||||
|         meta_window_x11_create_sync_request_alarm (window); |         meta_window_x11_create_sync_request_alarm (window); | ||||||
|  |  | ||||||
|       if (window->size_hints.width_inc > 2 || window->size_hints.height_inc > 2) |       if (window->size_hints.width_inc > 2 || window->size_hints.height_inc > 2) | ||||||
| @@ -1038,18 +1157,20 @@ static gboolean | |||||||
| sync_request_timeout (gpointer data) | sync_request_timeout (gpointer data) | ||||||
| { | { | ||||||
|   MetaWindow *window = data; |   MetaWindow *window = data; | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (META_WINDOW_X11 (window)); | ||||||
|  |  | ||||||
|   window->sync_request_timeout_id = 0; |   priv->sync_request_timeout_id = 0; | ||||||
|  |  | ||||||
|   /* We have now waited for more than a second for the |   /* We have now waited for more than a second for the | ||||||
|    * application to respond to the sync request |    * application to respond to the sync request | ||||||
|    */ |    */ | ||||||
|   window->disable_sync = TRUE; |   priv->disable_sync = TRUE; | ||||||
|  |  | ||||||
|   /* Reset the wait serial, so we don't continue freezing |   /* Reset the wait serial, so we don't continue freezing | ||||||
|    * window updates |    * window updates | ||||||
|    */ |    */ | ||||||
|   window->sync_request_wait_serial = 0; |   priv->sync_request_wait_serial = 0; | ||||||
|   meta_compositor_sync_updates_frozen (window->display->compositor, window); |   meta_compositor_sync_updates_frozen (window->display->compositor, window); | ||||||
|  |  | ||||||
|   if (window == window->display->grab_window && |   if (window == window->display->grab_window && | ||||||
| @@ -1068,6 +1189,9 @@ sync_request_timeout (gpointer data) | |||||||
| static void | static void | ||||||
| send_sync_request (MetaWindow *window) | send_sync_request (MetaWindow *window) | ||||||
| { | { | ||||||
|  |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|   MetaX11Display *x11_display = window->display->x11_display; |   MetaX11Display *x11_display = window->display->x11_display; | ||||||
|   XClientMessageEvent ev; |   XClientMessageEvent ev; | ||||||
|   gint64 wait_serial; |   gint64 wait_serial; | ||||||
| @@ -1079,9 +1203,9 @@ send_sync_request (MetaWindow *window) | |||||||
|    * for the old style. The increment of 240 is specified by the EWMH |    * for the old style. The increment of 240 is specified by the EWMH | ||||||
|    * and is (1 second) * (60fps) * (an increment of 4 per frame). |    * and is (1 second) * (60fps) * (an increment of 4 per frame). | ||||||
|    */ |    */ | ||||||
|   wait_serial = window->sync_request_serial + 240; |   wait_serial = priv->sync_request_serial + 240; | ||||||
|  |  | ||||||
|   window->sync_request_wait_serial = wait_serial; |   priv->sync_request_wait_serial = wait_serial; | ||||||
|  |  | ||||||
|   ev.type = ClientMessage; |   ev.type = ClientMessage; | ||||||
|   ev.window = window->xwindow; |   ev.window = window->xwindow; | ||||||
| @@ -1096,7 +1220,7 @@ send_sync_request (MetaWindow *window) | |||||||
|   ev.data.l[1] = meta_display_get_current_time (window->display); |   ev.data.l[1] = meta_display_get_current_time (window->display); | ||||||
|   ev.data.l[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff); |   ev.data.l[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff); | ||||||
|   ev.data.l[3] = wait_serial >> 32; |   ev.data.l[3] = wait_serial >> 32; | ||||||
|   ev.data.l[4] = window->extended_sync_request_counter ? 1 : 0; |   ev.data.l[4] = priv->extended_sync_request_counter ? 1 : 0; | ||||||
|  |  | ||||||
|   /* We don't need to trap errors here as we are already |   /* We don't need to trap errors here as we are already | ||||||
|    * inside an error_trap_push()/pop() pair. |    * inside an error_trap_push()/pop() pair. | ||||||
| @@ -1108,10 +1232,10 @@ send_sync_request (MetaWindow *window) | |||||||
|    * if this time expires, we consider the window unresponsive |    * if this time expires, we consider the window unresponsive | ||||||
|    * and resize it unsynchonized. |    * and resize it unsynchonized. | ||||||
|    */ |    */ | ||||||
|   window->sync_request_timeout_id = g_timeout_add (1000, |   priv->sync_request_timeout_id = g_timeout_add (1000, | ||||||
|                                                    sync_request_timeout, |                                                  sync_request_timeout, | ||||||
|                                                    window); |                                                  window); | ||||||
|   g_source_set_name_by_id (window->sync_request_timeout_id, |   g_source_set_name_by_id (priv->sync_request_timeout_id, | ||||||
|                            "[mutter] sync_request_timeout"); |                            "[mutter] sync_request_timeout"); | ||||||
|  |  | ||||||
|   meta_compositor_sync_updates_frozen (window->display->compositor, window); |   meta_compositor_sync_updates_frozen (window->display->compositor, window); | ||||||
| @@ -1329,7 +1453,7 @@ meta_window_x11_move_resize_internal (MetaWindow                *window, | |||||||
|    * will be left undisturbed for us to paint to the screen until |    * will be left undisturbed for us to paint to the screen until | ||||||
|    * the client finishes redrawing. |    * the client finishes redrawing. | ||||||
|    */ |    */ | ||||||
|   if (window->extended_sync_request_counter) |   if (priv->extended_sync_request_counter) | ||||||
|     configure_frame_first = TRUE; |     configure_frame_first = TRUE; | ||||||
|   else |   else | ||||||
|     configure_frame_first = size_dx + size_dy >= 0; |     configure_frame_first = size_dx + size_dy >= 0; | ||||||
| @@ -1357,10 +1481,10 @@ meta_window_x11_move_resize_internal (MetaWindow                *window, | |||||||
|  |  | ||||||
|       if (window == window->display->grab_window && |       if (window == window->display->grab_window && | ||||||
|           meta_grab_op_is_resizing (window->display->grab_op) && |           meta_grab_op_is_resizing (window->display->grab_op) && | ||||||
|           !window->disable_sync && |           !priv->disable_sync && | ||||||
|           window->sync_request_counter != None && |           priv->sync_request_counter != None && | ||||||
|           window->sync_request_alarm != None && |           priv->sync_request_alarm != None && | ||||||
|           window->sync_request_timeout_id == 0) |           priv->sync_request_timeout_id == 0) | ||||||
|         { |         { | ||||||
|           send_sync_request (window); |           send_sync_request (window); | ||||||
|         } |         } | ||||||
| @@ -1696,16 +1820,43 @@ meta_window_x11_is_stackable (MetaWindow *window) | |||||||
| static gboolean | static gboolean | ||||||
| meta_window_x11_are_updates_frozen (MetaWindow *window) | meta_window_x11_are_updates_frozen (MetaWindow *window) | ||||||
| { | { | ||||||
|   if (window->extended_sync_request_counter && |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|       window->sync_request_serial % 2 == 1) |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |  | ||||||
|  |   if (priv->extended_sync_request_counter && | ||||||
|  |       priv->sync_request_serial % 2 == 1) | ||||||
|     return TRUE; |     return TRUE; | ||||||
|  |  | ||||||
|   if (window->sync_request_serial < window->sync_request_wait_serial) |   if (priv->sync_request_serial < priv->sync_request_wait_serial) | ||||||
|     return TRUE; |     return TRUE; | ||||||
|  |  | ||||||
|   return FALSE; |   return FALSE; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static gboolean | ||||||
|  | meta_window_x11_has_pointer (MetaWindow *window) | ||||||
|  | { | ||||||
|  |   MetaX11Display *x11_display = window->display->x11_display; | ||||||
|  |   Window root, child; | ||||||
|  |   double root_x, root_y, x, y; | ||||||
|  |   XIButtonState buttons; | ||||||
|  |   XIModifierState mods; | ||||||
|  |   XIGroupState group; | ||||||
|  |  | ||||||
|  |   meta_x11_error_trap_push (x11_display); | ||||||
|  |   XIQueryPointer (x11_display->xdisplay, | ||||||
|  |                   META_VIRTUAL_CORE_POINTER_ID, | ||||||
|  |                   x11_display->xroot, | ||||||
|  |                   &root, &child, | ||||||
|  |                   &root_x, &root_y, &x, &y, | ||||||
|  |                   &buttons, &mods, &group); | ||||||
|  |   meta_x11_error_trap_pop (x11_display); | ||||||
|  |   free (buttons.mask); | ||||||
|  |  | ||||||
|  |   return meta_x11_display_lookup_x_window (x11_display, child) == window; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| meta_window_x11_class_init (MetaWindowX11Class *klass) | meta_window_x11_class_init (MetaWindowX11Class *klass) | ||||||
| { | { | ||||||
| @@ -1713,6 +1864,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) | |||||||
|  |  | ||||||
|   window_class->manage = meta_window_x11_manage; |   window_class->manage = meta_window_x11_manage; | ||||||
|   window_class->unmanage = meta_window_x11_unmanage; |   window_class->unmanage = meta_window_x11_unmanage; | ||||||
|  |   window_class->map = meta_window_x11_map; | ||||||
|  |   window_class->unmap = meta_window_x11_unmap; | ||||||
|   window_class->ping = meta_window_x11_ping; |   window_class->ping = meta_window_x11_ping; | ||||||
|   window_class->delete = meta_window_x11_delete; |   window_class->delete = meta_window_x11_delete; | ||||||
|   window_class->kill = meta_window_x11_kill; |   window_class->kill = meta_window_x11_kill; | ||||||
| @@ -1733,6 +1886,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) | |||||||
|   window_class->is_stackable = meta_window_x11_is_stackable; |   window_class->is_stackable = meta_window_x11_is_stackable; | ||||||
|   window_class->can_ping = meta_window_x11_can_ping; |   window_class->can_ping = meta_window_x11_can_ping; | ||||||
|   window_class->are_updates_frozen = meta_window_x11_are_updates_frozen; |   window_class->are_updates_frozen = meta_window_x11_are_updates_frozen; | ||||||
|  |   window_class->has_pointer = meta_window_x11_has_pointer; | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -3558,121 +3712,38 @@ meta_window_x11_set_allowed_actions_hint (MetaWindow *window) | |||||||
| #undef MAX_N_ACTIONS | #undef MAX_N_ACTIONS | ||||||
| } | } | ||||||
|  |  | ||||||
| void |  | ||||||
| meta_window_x11_create_sync_request_alarm (MetaWindow *window) |  | ||||||
| { |  | ||||||
|   MetaX11Display *x11_display = window->display->x11_display; |  | ||||||
|   XSyncAlarmAttributes values; |  | ||||||
|   XSyncValue init; |  | ||||||
|  |  | ||||||
|   if (window->sync_request_counter == None || |  | ||||||
|       window->sync_request_alarm != None) |  | ||||||
|     return; |  | ||||||
|  |  | ||||||
|   meta_x11_error_trap_push (x11_display); |  | ||||||
|  |  | ||||||
|   /* In the new (extended style), the counter value is initialized by |  | ||||||
|    * the client before mapping the window. In the old style, we're |  | ||||||
|    * responsible for setting the initial value of the counter. |  | ||||||
|    */ |  | ||||||
|   if (window->extended_sync_request_counter) |  | ||||||
|     { |  | ||||||
|       if (!XSyncQueryCounter(x11_display->xdisplay, |  | ||||||
|                              window->sync_request_counter, |  | ||||||
|                              &init)) |  | ||||||
|         { |  | ||||||
|           meta_x11_error_trap_pop_with_return (x11_display); |  | ||||||
|           window->sync_request_counter = None; |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       window->sync_request_serial = |  | ||||||
|         XSyncValueLow32 (init) + ((gint64)XSyncValueHigh32 (init) << 32); |  | ||||||
|     } |  | ||||||
|   else |  | ||||||
|     { |  | ||||||
|       XSyncIntToValue (&init, 0); |  | ||||||
|       XSyncSetCounter (x11_display->xdisplay, |  | ||||||
|                        window->sync_request_counter, init); |  | ||||||
|       window->sync_request_serial = 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   values.trigger.counter = window->sync_request_counter; |  | ||||||
|   values.trigger.test_type = XSyncPositiveComparison; |  | ||||||
|  |  | ||||||
|   /* Initialize to one greater than the current value */ |  | ||||||
|   values.trigger.value_type = XSyncRelative; |  | ||||||
|   XSyncIntToValue (&values.trigger.wait_value, 1); |  | ||||||
|  |  | ||||||
|   /* After triggering, increment test_value by this until |  | ||||||
|    * until the test condition is false */ |  | ||||||
|   XSyncIntToValue (&values.delta, 1); |  | ||||||
|  |  | ||||||
|   /* we want events (on by default anyway) */ |  | ||||||
|   values.events = True; |  | ||||||
|  |  | ||||||
|   window->sync_request_alarm = XSyncCreateAlarm (x11_display->xdisplay, |  | ||||||
|                                                  XSyncCACounter | |  | ||||||
|                                                  XSyncCAValueType | |  | ||||||
|                                                  XSyncCAValue | |  | ||||||
|                                                  XSyncCATestType | |  | ||||||
|                                                  XSyncCADelta | |  | ||||||
|                                                  XSyncCAEvents, |  | ||||||
|                                                  &values); |  | ||||||
|  |  | ||||||
|   if (meta_x11_error_trap_pop_with_return (x11_display) == Success) |  | ||||||
|     meta_x11_display_register_sync_alarm (x11_display, &window->sync_request_alarm, window); |  | ||||||
|   else |  | ||||||
|     { |  | ||||||
|       window->sync_request_alarm = None; |  | ||||||
|       window->sync_request_counter = None; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| meta_window_x11_destroy_sync_request_alarm (MetaWindow *window) |  | ||||||
| { |  | ||||||
|   MetaX11Display *x11_display = window->display->x11_display; |  | ||||||
|  |  | ||||||
|   if (window->sync_request_alarm != None) |  | ||||||
|     { |  | ||||||
|       /* Has to be unregistered _before_ clearing the structure field */ |  | ||||||
|       meta_x11_display_unregister_sync_alarm (x11_display, window->sync_request_alarm); |  | ||||||
|       XSyncDestroyAlarm (x11_display->xdisplay, |  | ||||||
|                          window->sync_request_alarm); |  | ||||||
|       window->sync_request_alarm = None; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void | void | ||||||
| meta_window_x11_update_sync_request_counter (MetaWindow *window, | meta_window_x11_update_sync_request_counter (MetaWindow *window, | ||||||
|                                              gint64      new_counter_value) |                                              gint64      new_counter_value) | ||||||
| { | { | ||||||
|  |   MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|   gboolean needs_frame_drawn = FALSE; |   gboolean needs_frame_drawn = FALSE; | ||||||
|   gboolean no_delay_frame = FALSE; |   gboolean no_delay_frame = FALSE; | ||||||
|  |  | ||||||
|   if (window->extended_sync_request_counter && new_counter_value % 2 == 0) |   if (priv->extended_sync_request_counter && new_counter_value % 2 == 0) | ||||||
|     { |     { | ||||||
|       needs_frame_drawn = TRUE; |       needs_frame_drawn = TRUE; | ||||||
|       no_delay_frame = new_counter_value == window->sync_request_serial + 1; |       no_delay_frame = new_counter_value == priv->sync_request_serial + 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   window->sync_request_serial = new_counter_value; |   priv->sync_request_serial = new_counter_value; | ||||||
|   meta_compositor_sync_updates_frozen (window->display->compositor, window); |   meta_compositor_sync_updates_frozen (window->display->compositor, window); | ||||||
|  |  | ||||||
|   if (window == window->display->grab_window && |   if (window == window->display->grab_window && | ||||||
|       meta_grab_op_is_resizing (window->display->grab_op) && |       meta_grab_op_is_resizing (window->display->grab_op) && | ||||||
|       new_counter_value >= window->sync_request_wait_serial && |       new_counter_value >= priv->sync_request_wait_serial && | ||||||
|       (!window->extended_sync_request_counter || new_counter_value % 2 == 0) && |       (!priv->extended_sync_request_counter || new_counter_value % 2 == 0) && | ||||||
|       window->sync_request_timeout_id) |       priv->sync_request_timeout_id) | ||||||
|     { |     { | ||||||
|       meta_topic (META_DEBUG_RESIZING, |       meta_topic (META_DEBUG_RESIZING, | ||||||
|                   "Alarm event received last motion x = %d y = %d\n", |                   "Alarm event received last motion x = %d y = %d\n", | ||||||
|                   window->display->grab_latest_motion_x, |                   window->display->grab_latest_motion_x, | ||||||
|                   window->display->grab_latest_motion_y); |                   window->display->grab_latest_motion_y); | ||||||
|  |  | ||||||
|       g_source_remove (window->sync_request_timeout_id); |       g_source_remove (priv->sync_request_timeout_id); | ||||||
|       window->sync_request_timeout_id = 0; |       priv->sync_request_timeout_id = 0; | ||||||
|  |  | ||||||
|       /* This means we are ready for another configure; |       /* This means we are ready for another configure; | ||||||
|        * no pointer round trip here, to keep in sync */ |        * no pointer round trip here, to keep in sync */ | ||||||
| @@ -3687,7 +3758,7 @@ meta_window_x11_update_sync_request_counter (MetaWindow *window, | |||||||
|    * the application has come to its senses (maybe it was just |    * the application has come to its senses (maybe it was just | ||||||
|    * busy with a pagefault or a long computation). |    * busy with a pagefault or a long computation). | ||||||
|    */ |    */ | ||||||
|   window->disable_sync = FALSE; |   priv->disable_sync = FALSE; | ||||||
|  |  | ||||||
|   if (needs_frame_drawn) |   if (needs_frame_drawn) | ||||||
|     meta_compositor_queue_frame_drawn (window->display->compositor, window, |     meta_compositor_queue_frame_drawn (window->display->compositor, window, | ||||||
| @@ -3699,3 +3770,86 @@ meta_window_x11_get_toplevel_xwindow (MetaWindow *window) | |||||||
| { | { | ||||||
|   return window->frame ? window->frame->xwindow : window->xwindow; |   return window->frame ? window->frame->xwindow : window->xwindow; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int64_t | ||||||
|  | meta_window_x11_get_sync_request_serial (MetaWindowX11 *window_x11) | ||||||
|  | { | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |  | ||||||
|  |   g_return_val_if_fail (META_IS_WINDOW_X11 (window_x11), -1); | ||||||
|  |  | ||||||
|  |   return priv->sync_request_serial; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gboolean | ||||||
|  | meta_window_x11_has_sync_request_alarm (MetaWindowX11 *window_x11) | ||||||
|  | { | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |  | ||||||
|  |   g_return_val_if_fail (META_IS_WINDOW_X11 (window_x11), FALSE); | ||||||
|  |  | ||||||
|  |   return !priv->disable_sync && | ||||||
|  |           priv->sync_request_alarm != None; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gboolean | ||||||
|  | meta_window_x11_is_sync_request_scheduled (MetaWindowX11 *window_x11) | ||||||
|  | { | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |  | ||||||
|  |   g_return_val_if_fail (META_IS_WINDOW_X11 (window_x11), FALSE); | ||||||
|  |  | ||||||
|  |   return priv->sync_request_timeout_id != 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gboolean | ||||||
|  | meta_window_x11_has_extended_sync_request_counter (MetaWindowX11 *window_x11) | ||||||
|  | { | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |  | ||||||
|  |   g_return_val_if_fail (META_IS_WINDOW_X11 (window_x11), FALSE); | ||||||
|  |  | ||||||
|  |   return priv->extended_sync_request_counter; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | meta_window_x11_setup_sync_request_counter (MetaWindowX11 *window_x11, | ||||||
|  |                                             MetaPropValue *value) | ||||||
|  | { | ||||||
|  |   MetaWindowX11Private *priv = | ||||||
|  |     meta_window_x11_get_instance_private (window_x11); | ||||||
|  |   MetaWindow *window = META_WINDOW (window_x11); | ||||||
|  |  | ||||||
|  |   if (value->type == META_PROP_VALUE_INVALID) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   meta_window_x11_destroy_sync_request_alarm (window); | ||||||
|  |   priv->sync_request_counter = None; | ||||||
|  |  | ||||||
|  |   if (value->v.xcounter_list.n_counters == 0) | ||||||
|  |     { | ||||||
|  |       meta_warning ("_NET_WM_SYNC_REQUEST_COUNTER is empty\n"); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (value->v.xcounter_list.n_counters == 1) | ||||||
|  |     { | ||||||
|  |       priv->sync_request_counter = value->v.xcounter_list.counters[0]; | ||||||
|  |       priv->extended_sync_request_counter = FALSE; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       priv->sync_request_counter = value->v.xcounter_list.counters[1]; | ||||||
|  |       priv->extended_sync_request_counter = TRUE; | ||||||
|  |     } | ||||||
|  |   meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx (extended=%s)\n", | ||||||
|  |                 priv->sync_request_counter, | ||||||
|  |                 priv->extended_sync_request_counter ? "true" : "false"); | ||||||
|  |  | ||||||
|  |   if (priv->extended_sync_request_counter) | ||||||
|  |     meta_window_x11_create_sync_request_alarm (window); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -59,8 +59,6 @@ void meta_window_x11_set_wm_delete_window        (MetaWindow *window, | |||||||
|                                                   gboolean    delete_window); |                                                   gboolean    delete_window); | ||||||
| void meta_window_x11_set_allowed_actions_hint    (MetaWindow *window); | void meta_window_x11_set_allowed_actions_hint    (MetaWindow *window); | ||||||
|  |  | ||||||
| void meta_window_x11_create_sync_request_alarm   (MetaWindow *window); |  | ||||||
| void meta_window_x11_destroy_sync_request_alarm  (MetaWindow *window); |  | ||||||
| void meta_window_x11_update_sync_request_counter (MetaWindow *window, | void meta_window_x11_update_sync_request_counter (MetaWindow *window, | ||||||
|                                                   gint64      new_counter_value); |                                                   gint64      new_counter_value); | ||||||
|  |  | ||||||
| @@ -81,4 +79,10 @@ void     meta_window_x11_configure_notify        (MetaWindow      *window, | |||||||
|  |  | ||||||
| Window   meta_window_x11_get_toplevel_xwindow    (MetaWindow *window); | Window   meta_window_x11_get_toplevel_xwindow    (MetaWindow *window); | ||||||
|  |  | ||||||
|  | int64_t  meta_window_x11_get_sync_request_serial   (MetaWindowX11 *window_x11); | ||||||
|  | gboolean meta_window_x11_is_sync_request_scheduled (MetaWindowX11 *window_x11); | ||||||
|  | gboolean meta_window_x11_has_sync_request_alarm    (MetaWindowX11 *window_x11); | ||||||
|  |  | ||||||
|  | gboolean meta_window_x11_has_extended_sync_request_counter (MetaWindowX11 *window_x11); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user