[metacity] move sync alarms to be per-window and permanent



commit 23fcfbf17ed493f8df5e2059422b5bbd51b23da2
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Wed Jun 8 11:26:03 2011 -0400

    move sync alarms to be per-window and permanent
    
    Instead of creating a new alarm each time we resize a window
    interactively, create an alarm the first time we resize a window
    and keep it around permanently until we unmanage the window.
    Doing it this way will be useful when we allow the application to
    spontaneously generate sync request updates to indicate
    frames it is drawing.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685463

 src/core/display-private.h |   11 ++++-
 src/core/display.c         |  109 ++++++++++++++++++--------------------------
 src/core/window-private.h  |    5 ++
 src/core/window-props.c    |    2 +
 src/core/window.c          |   80 +++++++++++++++++++++++++++++++-
 5 files changed, 138 insertions(+), 69 deletions(-)
---
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 50b9dd1..03b1079 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -204,8 +204,6 @@ struct _MetaDisplay
   int         xkb_base_event_type;
   guint32     last_bell_time;
 #endif
-  /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
-  XSyncAlarm  grab_sync_request_alarm;
   int        grab_resize_timeout_id;
 
   /* Keybindings stuff */
@@ -326,6 +324,15 @@ void        meta_display_register_x_window   (MetaDisplay *display,
                                               MetaWindow  *window);
 void        meta_display_unregister_x_window (MetaDisplay *display,
                                               Window       xwindow);
+
+MetaWindow* meta_display_lookup_sync_alarm     (MetaDisplay *display,
+                                                XSyncAlarm   alarm);
+void        meta_display_register_sync_alarm   (MetaDisplay *display,
+                                                XSyncAlarm  *alarmp,
+                                                MetaWindow  *window);
+void        meta_display_unregister_sync_alarm (MetaDisplay *display,
+                                                XSyncAlarm   alarm);
+
 /* Return whether the xwindow is a no focus window for any of the screens */
 gboolean    meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
                                                        Window xwindow);
diff --git a/src/core/display.c b/src/core/display.c
index 8ca09fa..31a0e43 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -335,8 +335,6 @@ meta_display_open (void)
   the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
                                                   terminal has the focus */
 
-  the_display->grab_sync_request_alarm = None;
-
   /* FIXME copy the checks from GDK probably */
   the_display->static_gravity_works = g_getenv ("METACITY_USE_STATIC_GRAVITY") != NULL;
 
@@ -1787,18 +1785,26 @@ event_callback (XEvent   *event,
     }
 
   if (META_DISPLAY_HAS_XSYNC (display) &&
-      event->type == (display->xsync_event_base + XSyncAlarmNotify) &&
-      ((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
+      event->type == (display->xsync_event_base + XSyncAlarmNotify))
     {
-      XSyncValue value;
-      guint64 new_counter_value;
+      Window alarm_xwindow;
+      MetaWindow *alarm_window;
+
+      alarm_xwindow = ((XSyncAlarmNotifyEvent *) event)->alarm;
+      alarm_window = meta_display_lookup_sync_alarm (display, alarm_xwindow);
 
-      value = ((XSyncAlarmNotifyEvent *) event)->counter_value;
-      new_counter_value = XSyncValueLow32 (value) + ((gint64) XSyncValueHigh32 (value) << 32);
+      if (alarm_window != NULL)
+        {
+          XSyncValue value;
+          guint64 new_counter_value;
 
-      meta_window_update_sync_request_counter (display->grab_window, new_counter_value);
+          value = ((XSyncAlarmNotifyEvent *) event)->counter_value;
+          new_counter_value = XSyncValueLow32 (value) + ((gint64) XSyncValueHigh32 (value) << 32);
 
-      filter_out_event = TRUE; /* GTK doesn't want to see this really */
+          meta_window_update_sync_request_counter (display->grab_window, new_counter_value);
+
+          filter_out_event = TRUE; /* GTK doesn't want to see this really */
+        }
     }
 
   if (META_DISPLAY_HAS_SHAPE (display) &&
@@ -3284,6 +3290,32 @@ meta_display_unregister_x_window (MetaDisplay *display,
   remove_pending_pings_for_window (display, xwindow);
 }
 
+MetaWindow*
+meta_display_lookup_sync_alarm (MetaDisplay *display,
+                                XSyncAlarm   alarm)
+{
+  return g_hash_table_lookup (display->window_ids, &alarm);
+}
+
+void
+meta_display_register_sync_alarm (MetaDisplay *display,
+                                  XSyncAlarm  *alarmp,
+                                  MetaWindow  *window)
+{
+  g_return_if_fail (g_hash_table_lookup (display->window_ids, alarmp) == NULL);
+
+  g_hash_table_insert (display->window_ids, alarmp, window);
+}
+
+void
+meta_display_unregister_sync_alarm (MetaDisplay *display,
+                                    XSyncAlarm   alarm)
+{
+  g_return_if_fail (g_hash_table_lookup (display->window_ids, &alarm) != NULL);
+
+  g_hash_table_remove (display->window_ids, &alarm);
+}
+
 gboolean
 meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
                                            Window xwindow)
@@ -3632,7 +3664,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
   display->grab_last_moveresize_time.tv_usec = 0;
   display->grab_motion_notify_time = 0;
   display->grab_old_window_stacking = NULL;
-  display->grab_sync_request_alarm = None;
   display->grab_last_user_action_was_snap = FALSE;
   display->grab_was_cancelled = FALSE;
   display->grab_frame_action = frame_action;
@@ -3664,53 +3695,10 @@ meta_display_begin_grab_op (MetaDisplay *display,
           meta_grab_op_is_resizing (display->grab_op) &&
           display->grab_window->sync_request_counter != None)
         {
-          XSyncAlarmAttributes values;
-          XSyncValue init;
-
-          meta_error_trap_push (display);
-
-          /* Set the counter to 0, so we know that the application's
-           * responses to the client messages will always trigger
-           * a PositiveTransition
-           */
+          meta_window_create_sync_request_alarm (display->grab_window);
 
-          XSyncIntToValue (&init, 0);
-          XSyncSetCounter (display->xdisplay,
-                           display->grab_window->sync_request_counter, init);
-
-          display->grab_window->sync_request_serial = 0;
-          display->grab_window->sync_request_time.tv_sec = 0;
-          display->grab_window->sync_request_time.tv_usec = 0;
-
-          values.trigger.counter = display->grab_window->sync_request_counter;
-          values.trigger.value_type = XSyncAbsolute;
-          values.trigger.test_type = XSyncPositiveTransition;
-          XSyncIntToValue (&values.trigger.wait_value,
-                           display->grab_window->sync_request_serial + 1);
-
-          /* After triggering, increment test_value by this.
-           * (NOT wait_value above)
-           */
-          XSyncIntToValue (&values.delta, 1);
-
-          /* we want events (on by default anyway) */
-          values.events = True;
-
-          display->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay,
-                                                         XSyncCACounter |
-                                                         XSyncCAValueType |
-                                                         XSyncCAValue |
-                                                         XSyncCATestType |
-                                                         XSyncCADelta |
-                                                         XSyncCAEvents,
-                                                         &values);
-
-          if (meta_error_trap_pop_with_return (display) != Success)
-            display->grab_sync_request_alarm = None;
-
-          meta_topic (META_DEBUG_RESIZING,
-                      "Created update alarm 0x%lx\n",
-                      display->grab_sync_request_alarm);
+          window->sync_request_time.tv_sec = 0;
+          window->sync_request_time.tv_usec = 0;
         }
     }
 
@@ -3936,13 +3924,6 @@ meta_display_end_grab_op (MetaDisplay *display,
         meta_screen_ungrab_all_keys (display->grab_screen, timestamp);
     }
 
-  if (display->grab_sync_request_alarm != None)
-    {
-      XSyncDestroyAlarm (display->xdisplay,
-                         display->grab_sync_request_alarm);
-      display->grab_sync_request_alarm = None;
-    }
-
   /* Hide the tile preview if it exists */
   if (display->grab_screen->tile_preview)
     meta_tile_preview_hide (display->grab_screen->tile_preview);
diff --git a/src/core/window-private.h b/src/core/window-private.h
index fbd0bc1..dd65195 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -347,6 +347,8 @@ struct _MetaWindow
   XSyncCounter sync_request_counter;
   guint sync_request_serial;
   GTimeVal sync_request_time;
+  /* 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
@@ -647,6 +649,9 @@ void meta_window_refresh_resize_popup (MetaWindow *window);
 
 void meta_window_free_delete_dialog (MetaWindow *window);
 
+void meta_window_create_sync_request_alarm  (MetaWindow *window);
+void meta_window_destroy_sync_request_alarm (MetaWindow *window);
+
 void     meta_window_foreach_transient        (MetaWindow            *window,
                                                MetaWindowForeachFunc  func,
                                                void                  *data);
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 3ff601b..3366286 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -1004,6 +1004,8 @@ reload_update_counter (MetaWindow    *window,
     {
       XSyncCounter counter = value->v.xcounter;
 
+      meta_window_destroy_sync_request_alarm (window);
+
       window->sync_request_counter = counter;
       meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx\n",
                     window->sync_request_counter);
diff --git a/src/core/window.c b/src/core/window.c
index f1c7247..86e419c 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -434,6 +434,7 @@ meta_window_new (MetaDisplay    *display,
   window->sync_request_serial = 0;
   window->sync_request_time.tv_sec = 0;
   window->sync_request_time.tv_usec = 0;
+  window->sync_request_alarm = None;
 
   window->screen = display->screen;
 
@@ -1167,6 +1168,8 @@ meta_window_free (MetaWindow  *window,
   if (!window->override_redirect)
     meta_stack_remove (window->screen->stack, window);
 
+  meta_window_destroy_sync_request_alarm (window);
+
   if (window->frame)
     {
       /* The XReparentWindow call in meta_window_destroy_frame() moves the
@@ -3436,6 +3439,76 @@ static_gravity_works (MetaDisplay *display)
   return display->static_gravity_works;
 }
 
+void
+meta_window_create_sync_request_alarm (MetaWindow *window)
+{
+  XSyncAlarmAttributes values;
+  XSyncValue init;
+
+  if (window->sync_request_counter == None ||
+      window->sync_request_alarm != None)
+    return;
+
+  meta_error_trap_push (window->display);
+
+  /* Set the counter to 0, so we know that the application's
+   * responses to the client messages will always trigger
+   * a PositiveTransition
+   */
+  XSyncIntToValue (&init, 0);
+  XSyncSetCounter (window->display->xdisplay,
+                   window->sync_request_counter, init);
+  window->sync_request_serial = 0;
+
+  values.trigger.counter = window->sync_request_counter;
+  values.trigger.test_type = XSyncPositiveTransition;
+
+  /* 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 (window->display->xdisplay,
+                                                 XSyncCACounter |
+                                                 XSyncCAValueType |
+                                                 XSyncCAValue |
+                                                 XSyncCATestType |
+                                                 XSyncCADelta |
+                                                 XSyncCAEvents,
+                                                 &values);
+
+  if (meta_error_trap_pop_with_return (window->display) == Success)
+    {
+      meta_display_register_sync_alarm (window->display,
+                                        &window->sync_request_alarm,
+                                        window);
+    }
+  else
+    {
+      window->sync_request_alarm = None;
+      window->sync_request_counter = None;
+    }
+}
+
+void
+meta_window_destroy_sync_request_alarm (MetaWindow *window)
+{
+  if (window->sync_request_alarm != None)
+    {
+      /* Has to be unregistered _before_ clearing the structure field */
+      meta_display_unregister_sync_alarm (window->display, window->sync_request_alarm);
+
+      XSyncDestroyAlarm (window->display->xdisplay, window->sync_request_alarm);
+      window->sync_request_alarm = None;
+    }
+}
+
 static void
 send_sync_request (MetaWindow *window)
 {
@@ -3872,8 +3945,9 @@ meta_window_move_resize_internal (MetaWindow          *window,
 
       meta_error_trap_push (window->display);
 
-      if (window->sync_request_counter != None &&
-          window->display->grab_sync_request_alarm != None &&
+      if (window == window->display->grab_window &&
+          window->sync_request_counter != None &&
+          window->sync_request_alarm != None &&
           window->sync_request_time.tv_usec == 0 &&
           window->sync_request_time.tv_sec == 0)
         {
@@ -7247,7 +7321,7 @@ check_moveresize_frequency (MetaWindow *window,
   g_get_current_time (&current_time);
 
   if (!window->disable_sync &&
-      window->display->grab_sync_request_alarm != None)
+      window->sync_request_alarm != None)
     {
       if (window->sync_request_time.tv_sec != 0 ||
           window->sync_request_time.tv_usec != 0)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]