Compare commits
	
		
			5 Commits
		
	
	
		
			3.36.0
			...
			gbsneto/cl
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0c4fdb2d31 | ||
| 
						 | 
					4504a313f7 | ||
| 
						 | 
					ed7fc825e1 | ||
| 
						 | 
					43307c6b84 | ||
| 
						 | 
					b4d55325d7 | 
@@ -52,6 +52,7 @@
 | 
			
		||||
#include "compositor/compositor-private.h"
 | 
			
		||||
#include "core/display-private.h"
 | 
			
		||||
#include "meta/meta-cursor-tracker.h"
 | 
			
		||||
#include "meta/meta-x11-errors.h"
 | 
			
		||||
#include "meta/util.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaBackendX11Private
 | 
			
		||||
@@ -598,6 +599,10 @@ meta_backend_x11_warp_pointer (MetaBackend *backend,
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
 | 
			
		||||
  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,
 | 
			
		||||
                 META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
@@ -605,6 +610,10 @@ meta_backend_x11_warp_pointer (MetaBackend *backend,
 | 
			
		||||
                 meta_backend_x11_get_xwindow (x11),
 | 
			
		||||
                 0, 0, 0, 0,
 | 
			
		||||
                 x, y);
 | 
			
		||||
 | 
			
		||||
  if (display &&
 | 
			
		||||
      meta_x11_error_trap_pop_with_return (display->x11_display) != Success)
 | 
			
		||||
    meta_verbose ("Failed to warp pointer\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaLogicalMonitor *
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@
 | 
			
		||||
#include "meta/meta-x11-errors.h"
 | 
			
		||||
#include "meta/window.h"
 | 
			
		||||
#include "x11/meta-x11-display-private.h"
 | 
			
		||||
#include "x11/window-x11.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaWindowActorX11
 | 
			
		||||
{
 | 
			
		||||
@@ -366,9 +367,12 @@ meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor,
 | 
			
		||||
  if (meta_window_actor_is_destroyed (actor))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_assert (META_IS_WINDOW_X11 (window));
 | 
			
		||||
 | 
			
		||||
  frame = g_slice_new0 (FrameData);
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
@@ -485,13 +489,14 @@ meta_window_actor_x11_constructed (GObject *object)
 | 
			
		||||
  MetaWindowActor *window_actor = META_WINDOW_ACTOR (object);
 | 
			
		||||
  MetaWindow *window =
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
  /* 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.
 | 
			
		||||
   */
 | 
			
		||||
  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_actor_queue_frame_drawn (window_actor, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -403,9 +403,6 @@ struct _MetaWindow
 | 
			
		||||
  /* if TRUE we have a grab on the focus click buttons */
 | 
			
		||||
  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 */
 | 
			
		||||
  guint attached : 1;
 | 
			
		||||
 | 
			
		||||
@@ -431,21 +428,9 @@ struct _MetaWindow
 | 
			
		||||
  /* _NET_WM_WINDOW_OPACITY rescaled to 0xFF */
 | 
			
		||||
  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 */
 | 
			
		||||
  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
 | 
			
		||||
   * we get UnmapNotify with none pending then the client
 | 
			
		||||
   * is withdrawing the window.
 | 
			
		||||
@@ -532,6 +517,8 @@ struct _MetaWindowClass
 | 
			
		||||
 | 
			
		||||
  void (*manage)                 (MetaWindow *window);
 | 
			
		||||
  void (*unmanage)               (MetaWindow *window);
 | 
			
		||||
  void (*map)                    (MetaWindow *window);
 | 
			
		||||
  void (*unmap)                  (MetaWindow *window);
 | 
			
		||||
  void (*ping)                   (MetaWindow *window,
 | 
			
		||||
                                  guint32     serial);
 | 
			
		||||
  void (*delete)                 (MetaWindow *window,
 | 
			
		||||
@@ -570,6 +557,7 @@ struct _MetaWindowClass
 | 
			
		||||
  gboolean (*is_stackable)        (MetaWindow *window);
 | 
			
		||||
  gboolean (*can_ping)            (MetaWindow *window);
 | 
			
		||||
  gboolean (*are_updates_frozen)  (MetaWindow *window);
 | 
			
		||||
  gboolean (*has_pointer)         (MetaWindow *window);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* These differ from window->has_foo_func in that they consider
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,6 @@
 | 
			
		||||
#include "meta/group.h"
 | 
			
		||||
#include "meta/meta-cursor-tracker.h"
 | 
			
		||||
#include "meta/meta-enum-types.h"
 | 
			
		||||
#include "meta/meta-x11-errors.h"
 | 
			
		||||
#include "meta/prefs.h"
 | 
			
		||||
#include "ui/ui.h"
 | 
			
		||||
#include "x11/meta-x11-display-private.h"
 | 
			
		||||
@@ -799,6 +798,7 @@ client_window_should_be_mapped (MetaWindow *window)
 | 
			
		||||
static void
 | 
			
		||||
sync_client_window_mapped (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowClass *window_class = META_WINDOW_GET_CLASS (window);
 | 
			
		||||
  gboolean should_be_mapped = client_window_should_be_mapped (window);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (!window->override_redirect);
 | 
			
		||||
@@ -808,17 +808,15 @@ sync_client_window_mapped (MetaWindow *window)
 | 
			
		||||
 | 
			
		||||
  window->mapped = should_be_mapped;
 | 
			
		||||
 | 
			
		||||
  meta_x11_error_trap_push (window->display->x11_display);
 | 
			
		||||
  if (should_be_mapped)
 | 
			
		||||
    {
 | 
			
		||||
      XMapWindow (window->display->x11_display->xdisplay, window->xwindow);
 | 
			
		||||
      window_class->map (window);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      XUnmapWindow (window->display->x11_display->xdisplay, window->xwindow);
 | 
			
		||||
      window_class->unmap (window);
 | 
			
		||||
      window->unmaps_pending ++;
 | 
			
		||||
    }
 | 
			
		||||
  meta_x11_error_trap_pop (window->display->x11_display);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -999,11 +997,6 @@ _meta_window_shared_new (MetaDisplay         *display,
 | 
			
		||||
 | 
			
		||||
  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_desc (window);
 | 
			
		||||
 | 
			
		||||
@@ -1083,7 +1076,6 @@ _meta_window_shared_new (MetaDisplay         *display,
 | 
			
		||||
  window->calc_placement = FALSE;
 | 
			
		||||
  window->shaken_loose = FALSE;
 | 
			
		||||
  window->have_focus_click_grab = FALSE;
 | 
			
		||||
  window->disable_sync = FALSE;
 | 
			
		||||
 | 
			
		||||
  window->unmaps_pending = 0;
 | 
			
		||||
 | 
			
		||||
@@ -1528,12 +1520,6 @@ meta_window_unmanage (MetaWindow  *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)
 | 
			
		||||
    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
 | 
			
		||||
   * an artificial timeout-based throttled */
 | 
			
		||||
  if (!window->disable_sync &&
 | 
			
		||||
      window->sync_request_alarm != None)
 | 
			
		||||
  if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 &&
 | 
			
		||||
      meta_window_x11_has_sync_request_alarm (META_WINDOW_X11 (window)))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
   * 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;
 | 
			
		||||
 | 
			
		||||
  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,
 | 
			
		||||
 * return root coordinates where pointer ended up.
 | 
			
		||||
 */
 | 
			
		||||
static gboolean
 | 
			
		||||
static void
 | 
			
		||||
warp_grab_pointer (MetaWindow          *window,
 | 
			
		||||
                   MetaGrabOp           grab_op,
 | 
			
		||||
                   int                 *x,
 | 
			
		||||
@@ -6864,8 +6851,6 @@ warp_grab_pointer (MetaWindow          *window,
 | 
			
		||||
  *x = CLAMP (*x, 0, display_rect.width - 1);
 | 
			
		||||
  *y = CLAMP (*y, 0, display_rect.height - 1);
 | 
			
		||||
 | 
			
		||||
  meta_x11_error_trap_push (display->x11_display);
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_WINDOW_OPS,
 | 
			
		||||
              "Warping pointer to %d,%d with window at %d,%d\n",
 | 
			
		||||
              *x, *y, rect.x, rect.y);
 | 
			
		||||
@@ -6881,19 +6866,8 @@ warp_grab_pointer (MetaWindow          *window,
 | 
			
		||||
  meta_window_get_frame_rect (window,
 | 
			
		||||
                              &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_verbose ("Failed to warp pointer for window %s\n",
 | 
			
		||||
                    window->desc);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
  meta_backend_warp_pointer (meta_get_backend (), *x, *y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
meta_window_has_pointer (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    return window_has_pointer_wayland (window);
 | 
			
		||||
  else
 | 
			
		||||
    return window_has_pointer_x11 (window);
 | 
			
		||||
  return META_WINDOW_GET_CLASS (window)->has_pointer (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -111,6 +111,16 @@ meta_window_wayland_unmanage (MetaWindow *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
 | 
			
		||||
meta_window_wayland_ping (MetaWindow *window,
 | 
			
		||||
                          guint32     serial)
 | 
			
		||||
@@ -611,6 +621,21 @@ meta_window_wayland_are_updates_frozen (MetaWindow *window)
 | 
			
		||||
  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
 | 
			
		||||
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->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->delete = meta_window_wayland_delete;
 | 
			
		||||
  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->can_ping = meta_window_wayland_can_ping;
 | 
			
		||||
  window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen;
 | 
			
		||||
  window_class->has_pointer = meta_window_wayland_has_pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWindow *
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,21 @@ meta_window_xwayland_shortcuts_inhibited (MetaWindow         *window,
 | 
			
		||||
  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
 | 
			
		||||
meta_window_xwayland_get_property (GObject    *object,
 | 
			
		||||
                                   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->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->set_property = meta_window_xwayland_set_property;
 | 
			
		||||
 
 | 
			
		||||
@@ -1068,34 +1068,9 @@ reload_update_counter (MetaWindow    *window,
 | 
			
		||||
                       MetaPropValue *value,
 | 
			
		||||
                       gboolean       initial)
 | 
			
		||||
{
 | 
			
		||||
  if (value->type != META_PROP_VALUE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_x11_destroy_sync_request_alarm (window);
 | 
			
		||||
      window->sync_request_counter = None;
 | 
			
		||||
  MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
 | 
			
		||||
 | 
			
		||||
      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)
 | 
			
		||||
        {
 | 
			
		||||
          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);
 | 
			
		||||
    }
 | 
			
		||||
  meta_window_x11_setup_sync_request_counter (window_x11, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define FLAG_TOGGLED_ON(old,new,flag) \
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,8 @@
 | 
			
		||||
 | 
			
		||||
#include "core/window-private.h"
 | 
			
		||||
#include "x11/iconcache.h"
 | 
			
		||||
#include "x11/window-x11.h"
 | 
			
		||||
#include "x11/xprops.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@@ -72,8 +74,28 @@ struct _MetaWindowX11Private
 | 
			
		||||
  MetaIconCache icon_cache;
 | 
			
		||||
  Pixmap wm_hints_pixmap;
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
meta_window_x11_manage (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
@@ -588,6 +679,12 @@ meta_window_x11_unmanage (MetaWindow *window)
 | 
			
		||||
  MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
 | 
			
		||||
  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_window_x11_destroy_sync_request_alarm (window);
 | 
			
		||||
@@ -703,6 +800,28 @@ meta_window_x11_can_ping (MetaWindow *window)
 | 
			
		||||
  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
 | 
			
		||||
meta_window_x11_ping (MetaWindow *window,
 | 
			
		||||
                      guint32     serial)
 | 
			
		||||
@@ -895,7 +1014,7 @@ meta_window_x11_grab_op_began (MetaWindow *window,
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
      if (window->size_hints.width_inc > 2 || window->size_hints.height_inc > 2)
 | 
			
		||||
@@ -1038,18 +1157,20 @@ static gboolean
 | 
			
		||||
sync_request_timeout (gpointer 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
 | 
			
		||||
   * 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
 | 
			
		||||
   * window updates
 | 
			
		||||
   */
 | 
			
		||||
  window->sync_request_wait_serial = 0;
 | 
			
		||||
  priv->sync_request_wait_serial = 0;
 | 
			
		||||
  meta_compositor_sync_updates_frozen (window->display->compositor, window);
 | 
			
		||||
 | 
			
		||||
  if (window == window->display->grab_window &&
 | 
			
		||||
@@ -1068,6 +1189,9 @@ sync_request_timeout (gpointer data)
 | 
			
		||||
static void
 | 
			
		||||
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;
 | 
			
		||||
  XClientMessageEvent ev;
 | 
			
		||||
  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
 | 
			
		||||
   * 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.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[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff);
 | 
			
		||||
  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
 | 
			
		||||
   * 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
 | 
			
		||||
   * and resize it unsynchonized.
 | 
			
		||||
   */
 | 
			
		||||
  window->sync_request_timeout_id = g_timeout_add (1000,
 | 
			
		||||
                                                   sync_request_timeout,
 | 
			
		||||
                                                   window);
 | 
			
		||||
  g_source_set_name_by_id (window->sync_request_timeout_id,
 | 
			
		||||
  priv->sync_request_timeout_id = g_timeout_add (1000,
 | 
			
		||||
                                                 sync_request_timeout,
 | 
			
		||||
                                                 window);
 | 
			
		||||
  g_source_set_name_by_id (priv->sync_request_timeout_id,
 | 
			
		||||
                           "[mutter] sync_request_timeout");
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
   * the client finishes redrawing.
 | 
			
		||||
   */
 | 
			
		||||
  if (window->extended_sync_request_counter)
 | 
			
		||||
  if (priv->extended_sync_request_counter)
 | 
			
		||||
    configure_frame_first = TRUE;
 | 
			
		||||
  else
 | 
			
		||||
    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 &&
 | 
			
		||||
          meta_grab_op_is_resizing (window->display->grab_op) &&
 | 
			
		||||
          !window->disable_sync &&
 | 
			
		||||
          window->sync_request_counter != None &&
 | 
			
		||||
          window->sync_request_alarm != None &&
 | 
			
		||||
          window->sync_request_timeout_id == 0)
 | 
			
		||||
          !priv->disable_sync &&
 | 
			
		||||
          priv->sync_request_counter != None &&
 | 
			
		||||
          priv->sync_request_alarm != None &&
 | 
			
		||||
          priv->sync_request_timeout_id == 0)
 | 
			
		||||
        {
 | 
			
		||||
          send_sync_request (window);
 | 
			
		||||
        }
 | 
			
		||||
@@ -1696,16 +1820,43 @@ meta_window_x11_is_stackable (MetaWindow *window)
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_window_x11_are_updates_frozen (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  if (window->extended_sync_request_counter &&
 | 
			
		||||
      window->sync_request_serial % 2 == 1)
 | 
			
		||||
  MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
 | 
			
		||||
  MetaWindowX11Private *priv =
 | 
			
		||||
    meta_window_x11_get_instance_private (window_x11);
 | 
			
		||||
 | 
			
		||||
  if (priv->extended_sync_request_counter &&
 | 
			
		||||
      priv->sync_request_serial % 2 == 1)
 | 
			
		||||
    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 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
 | 
			
		||||
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->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->delete = meta_window_x11_delete;
 | 
			
		||||
  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->can_ping = meta_window_x11_can_ping;
 | 
			
		||||
  window_class->are_updates_frozen = meta_window_x11_are_updates_frozen;
 | 
			
		||||
  window_class->has_pointer = meta_window_x11_has_pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -3558,121 +3712,38 @@ meta_window_x11_set_allowed_actions_hint (MetaWindow *window)
 | 
			
		||||
#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
 | 
			
		||||
meta_window_x11_update_sync_request_counter (MetaWindow *window,
 | 
			
		||||
                                             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 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;
 | 
			
		||||
      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);
 | 
			
		||||
 | 
			
		||||
  if (window == window->display->grab_window &&
 | 
			
		||||
      meta_grab_op_is_resizing (window->display->grab_op) &&
 | 
			
		||||
      new_counter_value >= window->sync_request_wait_serial &&
 | 
			
		||||
      (!window->extended_sync_request_counter || new_counter_value % 2 == 0) &&
 | 
			
		||||
      window->sync_request_timeout_id)
 | 
			
		||||
      new_counter_value >= priv->sync_request_wait_serial &&
 | 
			
		||||
      (!priv->extended_sync_request_counter || new_counter_value % 2 == 0) &&
 | 
			
		||||
      priv->sync_request_timeout_id)
 | 
			
		||||
    {
 | 
			
		||||
      meta_topic (META_DEBUG_RESIZING,
 | 
			
		||||
                  "Alarm event received last motion x = %d y = %d\n",
 | 
			
		||||
                  window->display->grab_latest_motion_x,
 | 
			
		||||
                  window->display->grab_latest_motion_y);
 | 
			
		||||
 | 
			
		||||
      g_source_remove (window->sync_request_timeout_id);
 | 
			
		||||
      window->sync_request_timeout_id = 0;
 | 
			
		||||
      g_source_remove (priv->sync_request_timeout_id);
 | 
			
		||||
      priv->sync_request_timeout_id = 0;
 | 
			
		||||
 | 
			
		||||
      /* This means we are ready for another configure;
 | 
			
		||||
       * 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
 | 
			
		||||
   * busy with a pagefault or a long computation).
 | 
			
		||||
   */
 | 
			
		||||
  window->disable_sync = FALSE;
 | 
			
		||||
  priv->disable_sync = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (needs_frame_drawn)
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
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,
 | 
			
		||||
                                                  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);
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user