diff --git a/src/core/display-private.h b/src/core/display-private.h index 86d798fe3..f4f4077ea 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -221,10 +221,6 @@ struct _MetaDisplay #ifdef HAVE_XKB int xkb_base_event_type; guint32 last_bell_time; -#endif -#ifdef HAVE_XSYNC - /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ - XSyncAlarm grab_sync_request_alarm; #endif int grab_resize_timeout_id; @@ -370,6 +366,16 @@ void meta_display_register_x_window (MetaDisplay *display, void meta_display_unregister_x_window (MetaDisplay *display, Window xwindow); +#ifdef HAVE_XSYNC +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); +#endif /* HAVE_XSYNC */ + void meta_display_notify_window_created (MetaDisplay *display, MetaWindow *window); diff --git a/src/core/display.c b/src/core/display.c index a23665813..9a9de7fa3 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -531,10 +531,6 @@ meta_display_open (void) the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a terminal has the focus */ -#ifdef HAVE_XSYNC - the_display->grab_sync_request_alarm = None; -#endif - /* FIXME copy the checks from GDK probably */ the_display->static_gravity_works = g_getenv ("MUTTER_USE_STATIC_GRAVITY") != NULL; @@ -1939,15 +1935,20 @@ event_callback (XEvent *event, } #ifdef HAVE_XSYNC - if (META_DISPLAY_HAS_XSYNC (display) && - event->type == (display->xsync_event_base + XSyncAlarmNotify) && - ((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm) + if (META_DISPLAY_HAS_XSYNC (display) && + event->type == (display->xsync_event_base + XSyncAlarmNotify)) { - XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; - guint64 new_counter_value; - new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); - meta_window_update_sync_request_counter (display->grab_window, new_counter_value); - filter_out_event = TRUE; /* GTK doesn't want to see this really */ + MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display, + ((XSyncAlarmNotifyEvent*)event)->alarm); + + if (alarm_window != NULL) + { + XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; + guint64 new_counter_value; + new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); + meta_window_update_sync_request_counter (alarm_window, new_counter_value); + filter_out_event = TRUE; /* GTK doesn't want to see this really */ + } } #endif /* HAVE_XSYNC */ @@ -3555,6 +3556,39 @@ meta_display_unregister_x_window (MetaDisplay *display, remove_pending_pings_for_window (display, xwindow); } +#ifdef HAVE_XSYNC +/* We store sync alarms in the window ID hash table, because they are + * just more types of XIDs in the same global space, but we have + * typesafe functions to register/unregister for readability. + */ + +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); +} +#endif /* HAVE_XSYNC */ + void meta_display_notify_window_created (MetaDisplay *display, MetaWindow *window) @@ -3868,7 +3902,6 @@ meta_display_begin_grab_op (MetaDisplay *display, display->grab_motion_notify_time = 0; display->grab_old_window_stacking = NULL; #ifdef HAVE_XSYNC - display->grab_sync_request_alarm = None; display->grab_last_user_action_was_snap = FALSE; #endif display->grab_frame_action = frame_action; @@ -3889,55 +3922,11 @@ meta_display_begin_grab_op (MetaDisplay *display, #ifdef HAVE_XSYNC if ( meta_grab_op_is_resizing (display->grab_op) && - display->grab_window->sync_request_counter != None) + display->grab_window->sync_request_counter != None) { - XSyncAlarmAttributes values; - XSyncValue init; - - meta_error_trap_push_with_return (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 (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); + meta_window_create_sync_request_alarm (display->grab_window); + window->sync_request_time.tv_sec = 0; + window->sync_request_time.tv_usec = 0; } #endif } @@ -4050,14 +4039,6 @@ meta_display_end_grab_op (MetaDisplay *display, meta_screen_ungrab_all_keys (display->grab_screen, timestamp); } -#ifdef HAVE_XSYNC - if (display->grab_sync_request_alarm != None) - { - XSyncDestroyAlarm (display->xdisplay, - display->grab_sync_request_alarm); - display->grab_sync_request_alarm = None; - } -#endif /* HAVE_XSYNC */ display->grab_timestamp = 0; display->grab_window = NULL; diff --git a/src/core/window-private.h b/src/core/window-private.h index 9059f6f87..0ed3535c6 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; #endif /* Number of UnmapNotify that are caused by us, if @@ -626,6 +628,8 @@ 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_update_keyboard_resize (MetaWindow *window, gboolean update_cursor); diff --git a/src/core/window-props.c b/src/core/window-props.c index 744209070..e95ad4e33 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -882,6 +882,8 @@ reload_update_counter (MetaWindow *window, { if (value->type != META_PROP_VALUE_INVALID) { + meta_window_destroy_sync_request_alarm (window); + #ifdef HAVE_XSYNC XSyncCounter counter = value->v.xcounter; diff --git a/src/core/window.c b/src/core/window.c index f190c745e..cd04ae04e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1015,6 +1015,7 @@ meta_window_new_with_attrs (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; #endif window->screen = screen; @@ -1818,6 +1819,8 @@ meta_window_unmanage (MetaWindow *window, if (!window->override_redirect) meta_stack_remove (window->screen->stack, window); + meta_window_destroy_sync_request_alarm (window); + if (window->frame) meta_window_destroy_frame (window); @@ -4431,6 +4434,76 @@ static_gravity_works (MetaDisplay *display) return display->static_gravity_works; } +void +meta_window_create_sync_request_alarm (MetaWindow *window) +{ +#ifdef HAVE_XSYNC + XSyncAlarmAttributes values; + XSyncValue init; + + if (window->sync_request_counter == None || + window->sync_request_alarm != None) + return; + + meta_error_trap_push_with_return (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; + } +#endif +} + +void +meta_window_destroy_sync_request_alarm (MetaWindow *window) +{ +#ifdef HAVE_XSYNC + 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; + } +#endif /* HAVE_XSYNC */ +} + #ifdef HAVE_XSYNC static void send_sync_request (MetaWindow *window) @@ -4991,8 +5064,9 @@ meta_window_move_resize_internal (MetaWindow *window, meta_error_trap_push (window->display); #ifdef HAVE_XSYNC - 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) { @@ -8556,7 +8630,7 @@ check_moveresize_frequency (MetaWindow *window, #ifdef HAVE_XSYNC 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)