mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
Fix bug 143333, support for update counter spec, and 109362, schedule
Sat Jun 19 02:21:08 2004 Soeren Sandmann <sandmann@daimi.au.dk> Fix bug 143333, support for update counter spec, and 109362, schedule compensation events when events are ignored. * src/display.c (meta_display_open): Add _NET_WM_SYNC_REQUEST and _NET_WM_SYNC_REQUEST_COUNTER atoms. Remove the old METACITY_SYNC_COUNTER stuff. (meta_display_begin_op): Setup the sync counter * src/xprops.c, src/xprops.h, src/window-props.c, src/display.h: Add new atoms. * src/window.c (send_sync_request): new function. (meta_window_move_resize_internal): send a sync request before resizing. (check_move_resize_frequence): Rework logic to also check the SYNC case. If an event is ignored return the remaining time. (update_resize_timeout): Timeout that gets called when a compensation event is scheduled. (uddate_resize): schedule compensation events when an event is ignored. (meta_window_handle_mouse_grap_op_event): When an alarm is received and sync was turned off, turn it back on. * src/window.h (struct MetaWindow) Add some variables
This commit is contained in:
parent
952c1f415b
commit
4cfb5152f7
27
ChangeLog
27
ChangeLog
@ -1,3 +1,30 @@
|
|||||||
|
Sat Jun 19 02:21:08 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
Fix bug 143333, support for update counter spec, and 109362,
|
||||||
|
schedule compensation events when events are ignored.
|
||||||
|
|
||||||
|
* src/display.c (meta_display_open): Add _NET_WM_SYNC_REQUEST and
|
||||||
|
_NET_WM_SYNC_REQUEST_COUNTER atoms. Remove the old
|
||||||
|
METACITY_SYNC_COUNTER stuff.
|
||||||
|
(meta_display_begin_op): Setup the sync counter
|
||||||
|
|
||||||
|
* src/xprops.c, src/xprops.h, src/window-props.c, src/display.h:
|
||||||
|
Add new atoms.
|
||||||
|
|
||||||
|
* src/window.c (send_sync_request): new function.
|
||||||
|
(meta_window_move_resize_internal): send a sync request before
|
||||||
|
resizing.
|
||||||
|
(check_move_resize_frequence): Rework logic to also check the SYNC
|
||||||
|
case. If an event is ignored return the remaining time.
|
||||||
|
(update_resize_timeout): Timeout that gets called when a
|
||||||
|
compensation event is scheduled.
|
||||||
|
(uddate_resize): schedule compensation events when an event is
|
||||||
|
ignored.
|
||||||
|
(meta_window_handle_mouse_grap_op_event): When an alarm is
|
||||||
|
received and sync was turned off, turn it back on.
|
||||||
|
|
||||||
|
* src/window.h (struct MetaWindow) Add some variables
|
||||||
|
|
||||||
2004-06-16 Havoc Pennington <hp@redhat.com>
|
2004-06-16 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* configure.in: bump version, add the UNSTABLE note
|
* configure.in: bump version, add the UNSTABLE note
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Havoc Pennington
|
* Copyright (C) 2001 Havoc Pennington
|
||||||
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
|
||||||
* Copyright (C) 2003, 2004 Rob Adams
|
* Copyright (C) 2003, 2004 Rob Adams
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@ -270,8 +270,8 @@ meta_display_open (const char *name)
|
|||||||
"_NET_WM_STATE_BELOW",
|
"_NET_WM_STATE_BELOW",
|
||||||
"_NET_STARTUP_ID",
|
"_NET_STARTUP_ID",
|
||||||
"_METACITY_TOGGLE_VERBOSE",
|
"_METACITY_TOGGLE_VERBOSE",
|
||||||
"_METACITY_UPDATE_COUNTER",
|
"_NET_WM_SYNC_REQUEST",
|
||||||
"SYNC_COUNTER",
|
"_NET_WM_SYNC_REQUEST_COUNTER",
|
||||||
"_GNOME_PANEL_ACTION",
|
"_GNOME_PANEL_ACTION",
|
||||||
"_GNOME_PANEL_ACTION_MAIN_MENU",
|
"_GNOME_PANEL_ACTION_MAIN_MENU",
|
||||||
"_GNOME_PANEL_ACTION_RUN_DIALOG",
|
"_GNOME_PANEL_ACTION_RUN_DIALOG",
|
||||||
@ -323,7 +323,7 @@ meta_display_open (const char *name)
|
|||||||
display->expected_focus_window = NULL;
|
display->expected_focus_window = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
display->grab_update_alarm = None;
|
display->grab_sync_request_alarm = None;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME copy the checks from GDK probably */
|
/* FIXME copy the checks from GDK probably */
|
||||||
@ -416,8 +416,8 @@ meta_display_open (const char *name)
|
|||||||
display->atom_net_wm_state_below = atoms[71];
|
display->atom_net_wm_state_below = atoms[71];
|
||||||
display->atom_net_startup_id = atoms[72];
|
display->atom_net_startup_id = atoms[72];
|
||||||
display->atom_metacity_toggle_verbose = atoms[73];
|
display->atom_metacity_toggle_verbose = atoms[73];
|
||||||
display->atom_metacity_update_counter = atoms[74];
|
display->atom_net_wm_sync_request = atoms[74];
|
||||||
display->atom_sync_counter = atoms[75];
|
display->atom_net_wm_sync_request_counter = atoms[75];
|
||||||
display->atom_gnome_panel_action = atoms[76];
|
display->atom_gnome_panel_action = atoms[76];
|
||||||
display->atom_gnome_panel_action_main_menu = atoms[77];
|
display->atom_gnome_panel_action_main_menu = atoms[77];
|
||||||
display->atom_gnome_panel_action_run_dialog = atoms[78];
|
display->atom_gnome_panel_action_run_dialog = atoms[78];
|
||||||
@ -1264,7 +1264,7 @@ event_callback (XEvent *event,
|
|||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
if (META_DISPLAY_HAS_XSYNC (display) &&
|
if (META_DISPLAY_HAS_XSYNC (display) &&
|
||||||
event->type == (display->xsync_event_base + XSyncAlarmNotify) &&
|
event->type == (display->xsync_event_base + XSyncAlarmNotify) &&
|
||||||
((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_update_alarm)
|
((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
|
||||||
{
|
{
|
||||||
filter_out_event = TRUE; /* GTK doesn't want to see this really */
|
filter_out_event = TRUE; /* GTK doesn't want to see this really */
|
||||||
|
|
||||||
@ -2969,10 +2969,16 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
display->grab_last_moveresize_time.tv_usec = 0;
|
display->grab_last_moveresize_time.tv_usec = 0;
|
||||||
display->grab_motion_notify_time = 0;
|
display->grab_motion_notify_time = 0;
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
display->grab_update_alarm = None;
|
display->grab_sync_request_alarm = None;
|
||||||
#endif
|
#endif
|
||||||
display->grab_was_cancelled = FALSE;
|
display->grab_was_cancelled = FALSE;
|
||||||
|
|
||||||
|
if (display->grab_resize_timeout_id)
|
||||||
|
{
|
||||||
|
g_source_remove (display->grab_resize_timeout_id);
|
||||||
|
display->grab_resize_timeout_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (display->grab_window)
|
if (display->grab_window)
|
||||||
{
|
{
|
||||||
display->grab_initial_window_pos = display->grab_window->rect;
|
display->grab_initial_window_pos = display->grab_window->rect;
|
||||||
@ -3007,17 +3013,31 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
if (!display->grab_wireframe_active &&
|
if (!display->grab_wireframe_active &&
|
||||||
meta_grab_op_is_resizing (display->grab_op) &&
|
meta_grab_op_is_resizing (display->grab_op) &&
|
||||||
display->grab_window->update_counter != None)
|
display->grab_window->sync_request_counter != None)
|
||||||
{
|
{
|
||||||
XSyncAlarmAttributes values;
|
XSyncAlarmAttributes values;
|
||||||
|
XSyncValue init;
|
||||||
|
|
||||||
/* trigger when we make a positive transition to a value
|
meta_error_trap_push_with_return (display);
|
||||||
* one higher than the current value.
|
|
||||||
|
/* Set the counter to 0, so we know that the application's
|
||||||
|
* responses to the client messages will always trigger
|
||||||
|
* a PositiveTransition
|
||||||
*/
|
*/
|
||||||
values.trigger.counter = display->grab_window->update_counter;
|
|
||||||
values.trigger.value_type = XSyncRelative;
|
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;
|
values.trigger.test_type = XSyncPositiveTransition;
|
||||||
XSyncIntToValue (&values.trigger.wait_value, 1);
|
XSyncIntToValue (&values.trigger.wait_value,
|
||||||
|
display->grab_window->sync_request_serial + 1);
|
||||||
|
|
||||||
/* After triggering, increment test_value by this.
|
/* After triggering, increment test_value by this.
|
||||||
* (NOT wait_value above)
|
* (NOT wait_value above)
|
||||||
@ -3027,8 +3047,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
/* we want events (on by default anyway) */
|
/* we want events (on by default anyway) */
|
||||||
values.events = True;
|
values.events = True;
|
||||||
|
|
||||||
meta_error_trap_push_with_return (display);
|
display->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay,
|
||||||
display->grab_update_alarm = XSyncCreateAlarm (display->xdisplay,
|
|
||||||
XSyncCACounter |
|
XSyncCACounter |
|
||||||
XSyncCAValueType |
|
XSyncCAValueType |
|
||||||
XSyncCAValue |
|
XSyncCAValue |
|
||||||
@ -3036,12 +3055,13 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
XSyncCADelta |
|
XSyncCADelta |
|
||||||
XSyncCAEvents,
|
XSyncCAEvents,
|
||||||
&values);
|
&values);
|
||||||
|
|
||||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||||
display->grab_update_alarm = None;
|
display->grab_sync_request_alarm = None;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
meta_topic (META_DEBUG_RESIZING,
|
||||||
"Created update alarm 0x%lx\n",
|
"Created update alarm 0x%lx\n",
|
||||||
display->grab_update_alarm);
|
display->grab_sync_request_alarm);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -3138,10 +3158,11 @@ meta_display_end_grab_op (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
if (display->grab_update_alarm != None)
|
if (display->grab_sync_request_alarm != None)
|
||||||
{
|
{
|
||||||
XSyncDestroyAlarm (display->xdisplay,
|
XSyncDestroyAlarm (display->xdisplay,
|
||||||
display->grab_update_alarm);
|
display->grab_sync_request_alarm);
|
||||||
|
display->grab_sync_request_alarm = None;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_XSYNC */
|
#endif /* HAVE_XSYNC */
|
||||||
|
|
||||||
@ -3177,6 +3198,12 @@ meta_display_end_grab_op (MetaDisplay *display,
|
|||||||
meta_ui_resize_popup_free (display->grab_resize_popup);
|
meta_ui_resize_popup_free (display->grab_resize_popup);
|
||||||
display->grab_resize_popup = NULL;
|
display->grab_resize_popup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (display->grab_resize_timeout_id)
|
||||||
|
{
|
||||||
|
g_source_remove (display->grab_resize_timeout_id);
|
||||||
|
display->grab_resize_timeout_id = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -166,8 +166,8 @@ struct _MetaDisplay
|
|||||||
Atom atom_net_wm_state_below;
|
Atom atom_net_wm_state_below;
|
||||||
Atom atom_net_startup_id;
|
Atom atom_net_startup_id;
|
||||||
Atom atom_metacity_toggle_verbose;
|
Atom atom_metacity_toggle_verbose;
|
||||||
Atom atom_metacity_update_counter;
|
Atom atom_net_wm_sync_request;
|
||||||
Atom atom_sync_counter;
|
Atom atom_net_wm_sync_request_counter;
|
||||||
Atom atom_gnome_panel_action;
|
Atom atom_gnome_panel_action;
|
||||||
Atom atom_gnome_panel_action_main_menu;
|
Atom atom_gnome_panel_action_main_menu;
|
||||||
Atom atom_gnome_panel_action_run_dialog;
|
Atom atom_gnome_panel_action_run_dialog;
|
||||||
@ -258,9 +258,10 @@ struct _MetaDisplay
|
|||||||
int xkb_base_event_type;
|
int xkb_base_event_type;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
/* alarm monitoring client's _METACITY_UPDATE_COUNTER */
|
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
|
||||||
XSyncAlarm grab_update_alarm;
|
XSyncAlarm grab_sync_request_alarm;
|
||||||
#endif
|
#endif
|
||||||
|
int grab_resize_timeout_id;
|
||||||
|
|
||||||
/* Keybindings stuff */
|
/* Keybindings stuff */
|
||||||
MetaKeyBinding *screen_bindings;
|
MetaKeyBinding *screen_bindings;
|
||||||
|
@ -385,7 +385,7 @@ init_update_counter (MetaDisplay *display,
|
|||||||
MetaPropValue *value)
|
MetaPropValue *value)
|
||||||
{
|
{
|
||||||
value->type = META_PROP_VALUE_SYNC_COUNTER;
|
value->type = META_PROP_VALUE_SYNC_COUNTER;
|
||||||
value->atom = display->atom_metacity_update_counter;
|
value->atom = display->atom_net_wm_sync_request_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -397,9 +397,9 @@ reload_update_counter (MetaWindow *window,
|
|||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
XSyncCounter counter = value->v.xcounter;
|
XSyncCounter counter = value->v.xcounter;
|
||||||
|
|
||||||
window->update_counter = counter;
|
window->sync_request_counter = counter;
|
||||||
meta_verbose ("Window has _METACITY_UPDATE_COUNTER 0x%lx\n",
|
meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx\n",
|
||||||
window->update_counter);
|
window->sync_request_counter);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -924,7 +924,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
|||||||
hooks[i].reload_func = reload_net_startup_id;
|
hooks[i].reload_func = reload_net_startup_id;
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
hooks[i].property = display->atom_metacity_update_counter;
|
hooks[i].property = display->atom_net_wm_sync_request_counter;
|
||||||
hooks[i].init_func = init_update_counter;
|
hooks[i].init_func = init_update_counter;
|
||||||
hooks[i].reload_func = reload_update_counter;
|
hooks[i].reload_func = reload_update_counter;
|
||||||
++i;
|
++i;
|
||||||
|
238
src/window.c
238
src/window.c
@ -357,7 +357,10 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
window->workspaces = NULL;
|
window->workspaces = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
window->update_counter = None;
|
window->sync_request_counter = None;
|
||||||
|
window->sync_request_serial = 0;
|
||||||
|
window->sync_request_time.tv_sec = 0;
|
||||||
|
window->sync_request_time.tv_usec = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window->screen = NULL;
|
window->screen = NULL;
|
||||||
@ -446,6 +449,7 @@ meta_window_new_with_attrs (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;
|
||||||
|
|
||||||
@ -528,7 +532,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
initial_props[i++] = XA_WM_ICON_NAME;
|
initial_props[i++] = XA_WM_ICON_NAME;
|
||||||
initial_props[i++] = display->atom_net_wm_desktop;
|
initial_props[i++] = display->atom_net_wm_desktop;
|
||||||
initial_props[i++] = display->atom_net_startup_id;
|
initial_props[i++] = display->atom_net_startup_id;
|
||||||
initial_props[i++] = display->atom_metacity_update_counter;
|
initial_props[i++] = display->atom_net_wm_sync_request_counter;
|
||||||
initial_props[i++] = XA_WM_NORMAL_HINTS;
|
initial_props[i++] = XA_WM_NORMAL_HINTS;
|
||||||
initial_props[i++] = display->atom_wm_protocols;
|
initial_props[i++] = display->atom_wm_protocols;
|
||||||
initial_props[i++] = XA_WM_HINTS;
|
initial_props[i++] = XA_WM_HINTS;
|
||||||
@ -2297,6 +2301,36 @@ get_mouse_deltas_for_resize (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
static void
|
||||||
|
send_sync_request (MetaWindow *window)
|
||||||
|
{
|
||||||
|
XSyncValue value;
|
||||||
|
XClientMessageEvent ev;
|
||||||
|
|
||||||
|
window->sync_request_serial++;
|
||||||
|
|
||||||
|
XSyncIntToValue (&value, window->sync_request_serial);
|
||||||
|
|
||||||
|
ev.type = ClientMessage;
|
||||||
|
ev.window = window->xwindow;
|
||||||
|
ev.message_type = window->display->atom_wm_protocols;
|
||||||
|
ev.format = 32;
|
||||||
|
ev.data.l[0] = window->display->atom_net_wm_sync_request;
|
||||||
|
ev.data.l[1] = meta_display_get_current_time (window->display);
|
||||||
|
ev.data.l[2] = XSyncValueLow32 (value);
|
||||||
|
ev.data.l[3] = XSyncValueHigh32 (value);
|
||||||
|
|
||||||
|
/* We don't need to trap errors here as we are already
|
||||||
|
* inside an error_trap_push()/pop() pair.
|
||||||
|
*/
|
||||||
|
XSendEvent (window->display->xdisplay,
|
||||||
|
window->xwindow, False, 0, (XEvent*) &ev);
|
||||||
|
|
||||||
|
g_get_current_time (&window->sync_request_time);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_move_resize_internal (MetaWindow *window,
|
meta_window_move_resize_internal (MetaWindow *window,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
@ -2627,10 +2661,20 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
meta_error_trap_push (window->display);
|
||||||
|
|
||||||
|
if (window->sync_request_counter != None &&
|
||||||
|
window->display->grab_sync_request_alarm != None &&
|
||||||
|
window->sync_request_time.tv_usec == 0 &&
|
||||||
|
window->sync_request_time.tv_sec == 0)
|
||||||
|
{
|
||||||
|
send_sync_request (window);
|
||||||
|
}
|
||||||
|
|
||||||
XConfigureWindow (window->display->xdisplay,
|
XConfigureWindow (window->display->xdisplay,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
mask,
|
mask,
|
||||||
&values);
|
&values);
|
||||||
|
|
||||||
meta_error_trap_pop (window->display, FALSE);
|
meta_error_trap_pop (window->display, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4364,12 +4408,12 @@ process_property_notify (MetaWindow *window,
|
|||||||
meta_window_reload_property (window,
|
meta_window_reload_property (window,
|
||||||
window->display->atom_net_startup_id);
|
window->display->atom_net_startup_id);
|
||||||
}
|
}
|
||||||
else if (event->atom == window->display->atom_metacity_update_counter)
|
else if (event->atom == window->display->atom_net_wm_sync_request_counter)
|
||||||
{
|
{
|
||||||
meta_verbose ("Property notify on %s for _METACITY_UPDATE_COUNTER\n", window->desc);
|
meta_verbose ("Property notify on %s for _NET_WM_SYNC_REQUEST_COUNTER\n", window->desc);
|
||||||
|
|
||||||
meta_window_reload_property (window,
|
meta_window_reload_property (window,
|
||||||
window->display->atom_metacity_update_counter);
|
window->display->atom_net_wm_sync_request_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -5802,59 +5846,94 @@ meta_window_show_menu (MetaWindow *window,
|
|||||||
meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static double
|
||||||
clear_moveresize_time (MetaWindow *window)
|
timeval_to_ms (const GTimeVal *timeval)
|
||||||
{
|
{
|
||||||
/* Forces the next update to actually do something */
|
return (timeval->tv_sec * G_USEC_PER_SEC + timeval->tv_usec) / 1000.0;
|
||||||
window->display->grab_last_moveresize_time.tv_sec = 0;
|
}
|
||||||
window->display->grab_last_moveresize_time.tv_usec = 0;
|
|
||||||
|
static double
|
||||||
|
time_diff (const GTimeVal *first,
|
||||||
|
const GTimeVal *second)
|
||||||
|
{
|
||||||
|
double first_ms = timeval_to_ms (first);
|
||||||
|
double second_ms = timeval_to_ms (second);
|
||||||
|
|
||||||
|
return first_ms - second_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
check_moveresize_frequency (MetaWindow *window)
|
check_moveresize_frequency (MetaWindow *window,
|
||||||
|
gdouble *remaining)
|
||||||
{
|
{
|
||||||
GTimeVal current_time;
|
GTimeVal current_time;
|
||||||
double elapsed;
|
|
||||||
double max_resizes_per_second;
|
|
||||||
|
|
||||||
g_get_current_time (¤t_time);
|
g_get_current_time (¤t_time);
|
||||||
|
|
||||||
/* use milliseconds, 1000 milliseconds/second */
|
|
||||||
elapsed =
|
|
||||||
((((double)current_time.tv_sec - window->display->grab_last_moveresize_time.tv_sec) * G_USEC_PER_SEC +
|
|
||||||
(current_time.tv_usec - window->display->grab_last_moveresize_time.tv_usec))) / 1000.0;
|
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
if (window->display->grab_update_alarm != None)
|
if (!window->disable_sync &&
|
||||||
max_resizes_per_second = 1.0; /* this is max resizes without
|
window->display->grab_sync_request_alarm != None)
|
||||||
* getting any alarms; we resize
|
|
||||||
* immediately if we get one.
|
|
||||||
* i.e. this is a timeout for the
|
|
||||||
* client getting stuck.
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
#endif /* HAVE_XSYNC */
|
|
||||||
max_resizes_per_second = 20.0;
|
|
||||||
|
|
||||||
#define EPSILON (1e-6)
|
|
||||||
if (elapsed >= 0.0 && elapsed < (1000.0 / max_resizes_per_second))
|
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
if (window->sync_request_time.tv_sec != 0 ||
|
||||||
"Delaying move/resize as only %g of %g seconds elapsed\n",
|
window->sync_request_time.tv_usec != 0)
|
||||||
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
{
|
||||||
|
double elapsed =
|
||||||
|
time_diff (¤t_time, &window->sync_request_time);
|
||||||
|
|
||||||
|
if (elapsed < 1000.0)
|
||||||
|
{
|
||||||
|
/* We want to be sure that the timeout happens at
|
||||||
|
* a time where elapsed will definitely be
|
||||||
|
* greater than 1000, so we can disable sync
|
||||||
|
*/
|
||||||
|
if (remaining)
|
||||||
|
*remaining = 1000.0 - elapsed + 100;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (elapsed < (0.0 - EPSILON)) /* handle clock getting set backward */
|
else
|
||||||
clear_moveresize_time (window);
|
{
|
||||||
|
/* We have now waited for more than a second for the
|
||||||
|
* application to respond to the sync request
|
||||||
|
*/
|
||||||
|
window->disable_sync = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No outstanding sync requests. Go ahead and resize
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* HAVE_XSYNC */
|
||||||
|
{
|
||||||
|
const double max_resizes_per_second = 25.0;
|
||||||
|
const double ms_between_resizes = 1000.0 / max_resizes_per_second;
|
||||||
|
double elapsed;
|
||||||
|
|
||||||
/* store latest time */
|
elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_time);
|
||||||
window->display->grab_last_moveresize_time = current_time;
|
|
||||||
|
if (elapsed >= 0.0 && elapsed < ms_between_resizes)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_RESIZING,
|
||||||
|
"Delaying move/resize as only %g of %g ms elapsed\n",
|
||||||
|
elapsed, ms_between_resizes);
|
||||||
|
|
||||||
|
if (remaining)
|
||||||
|
*remaining = (ms_between_resizes - elapsed);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
meta_topic (META_DEBUG_RESIZING,
|
||||||
" Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
|
" Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
|
||||||
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -6005,15 +6084,34 @@ update_move (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_resize (MetaWindow *window,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
gboolean force);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
update_resize_timeout (gpointer data)
|
||||||
|
{
|
||||||
|
MetaWindow *window = data;
|
||||||
|
|
||||||
|
update_resize (window,
|
||||||
|
window->display->grab_latest_motion_x,
|
||||||
|
window->display->grab_latest_motion_y,
|
||||||
|
TRUE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_resize (MetaWindow *window,
|
update_resize (MetaWindow *window,
|
||||||
int x, int y)
|
int x, int y,
|
||||||
|
gboolean force)
|
||||||
{
|
{
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
int new_w, new_h;
|
int new_w, new_h;
|
||||||
int gravity;
|
int gravity;
|
||||||
MetaRectangle old;
|
MetaRectangle old;
|
||||||
int new_x, new_y;
|
int new_x, new_y;
|
||||||
|
double remaining;
|
||||||
|
|
||||||
window->display->grab_latest_motion_x = x;
|
window->display->grab_latest_motion_x = x;
|
||||||
window->display->grab_latest_motion_y = y;
|
window->display->grab_latest_motion_y = y;
|
||||||
@ -6077,8 +6175,28 @@ update_resize (MetaWindow *window,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_moveresize_frequency (window))
|
if (!check_moveresize_frequency (window, &remaining) && !force)
|
||||||
|
{
|
||||||
|
/* we are ignoring an event here, so we schedule a
|
||||||
|
* compensation event when we would otherwise not ignore
|
||||||
|
* an event. Otherwise we can become stuck if the user never
|
||||||
|
* generates another event.
|
||||||
|
*/
|
||||||
|
if (!window->display->grab_resize_timeout_id)
|
||||||
|
{
|
||||||
|
window->display->grab_resize_timeout_id =
|
||||||
|
g_timeout_add ((int)remaining, update_resize_timeout, window);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove any scheduled compensation events */
|
||||||
|
if (window->display->grab_resize_timeout_id)
|
||||||
|
{
|
||||||
|
g_source_remove (window->display->grab_resize_timeout_id);
|
||||||
|
window->display->grab_resize_timeout_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
old = window->rect;
|
old = window->rect;
|
||||||
|
|
||||||
@ -6118,14 +6236,12 @@ update_resize (MetaWindow *window,
|
|||||||
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't actually resize the window, we clear the timestamp,
|
/* Store the latest resize time, if we actually resized. */
|
||||||
* so we'll quickly try again. Otherwise you get "stuck" because
|
if (window->rect.width != old.width &&
|
||||||
* the window doesn't increment its _METACITY_UPDATE_COUNTER when
|
window->rect.height != old.height)
|
||||||
* nothing happens.
|
{
|
||||||
*/
|
g_get_current_time (&window->display->grab_last_moveresize_time);
|
||||||
if (window->rect.width == old.width &&
|
}
|
||||||
window->rect.height == old.height)
|
|
||||||
clear_moveresize_time (window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -6217,6 +6333,14 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
window->display->grab_latest_motion_x,
|
window->display->grab_latest_motion_x,
|
||||||
window->display->grab_latest_motion_y);
|
window->display->grab_latest_motion_y);
|
||||||
|
|
||||||
|
/* If sync was previously disabled, turn it back on and hope
|
||||||
|
* the application has come to its senses (maybe it was just
|
||||||
|
* busy with a pagefault or a long computation).
|
||||||
|
*/
|
||||||
|
window->disable_sync = FALSE;
|
||||||
|
window->sync_request_time.tv_sec = 0;
|
||||||
|
window->sync_request_time.tv_usec = 0;
|
||||||
|
|
||||||
/* This means we are ready for another configure. */
|
/* This means we are ready for another configure. */
|
||||||
switch (window->display->grab_op)
|
switch (window->display->grab_op)
|
||||||
{
|
{
|
||||||
@ -6236,12 +6360,11 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||||
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||||
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||||
clear_moveresize_time (window); /* force update to do something */
|
|
||||||
|
|
||||||
/* no pointer round trip here, to keep in sync */
|
/* no pointer round trip here, to keep in sync */
|
||||||
update_resize (window,
|
update_resize (window,
|
||||||
window->display->grab_latest_motion_x,
|
window->display->grab_latest_motion_x,
|
||||||
window->display->grab_latest_motion_y);
|
window->display->grab_latest_motion_y,
|
||||||
|
TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -6255,16 +6378,17 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
if (meta_grab_op_is_moving (window->display->grab_op))
|
if (meta_grab_op_is_moving (window->display->grab_op))
|
||||||
{
|
{
|
||||||
clear_moveresize_time (window);
|
|
||||||
if (event->xbutton.root == window->screen->xroot)
|
if (event->xbutton.root == window->screen->xroot)
|
||||||
update_move (window, event->xbutton.state,
|
update_move (window, event->xbutton.state,
|
||||||
event->xbutton.x_root, event->xbutton.y_root);
|
event->xbutton.x_root, event->xbutton.y_root);
|
||||||
}
|
}
|
||||||
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
||||||
{
|
{
|
||||||
clear_moveresize_time (window);
|
|
||||||
if (event->xbutton.root == window->screen->xroot)
|
if (event->xbutton.root == window->screen->xroot)
|
||||||
update_resize (window, event->xbutton.x_root, event->xbutton.y_root);
|
update_resize (window,
|
||||||
|
event->xbutton.x_root,
|
||||||
|
event->xbutton.y_root,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_display_end_grab_op (window->display, event->xbutton.time);
|
meta_display_end_grab_op (window->display, event->xbutton.time);
|
||||||
@ -6291,7 +6415,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
event))
|
event))
|
||||||
update_resize (window,
|
update_resize (window,
|
||||||
event->xmotion.x_root,
|
event->xmotion.x_root,
|
||||||
event->xmotion.y_root);
|
event->xmotion.y_root,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -6311,7 +6436,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
if (event->xcrossing.root == window->screen->xroot)
|
if (event->xcrossing.root == window->screen->xroot)
|
||||||
update_resize (window,
|
update_resize (window,
|
||||||
event->xcrossing.x_root,
|
event->xcrossing.x_root,
|
||||||
event->xcrossing.y_root);
|
event->xcrossing.y_root,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -244,9 +244,14 @@ 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;
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
/* XSync update counter */
|
/* XSync update counter */
|
||||||
XSyncCounter update_counter;
|
XSyncCounter sync_request_counter;
|
||||||
|
guint sync_request_serial;
|
||||||
|
GTimeVal sync_request_time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Number of UnmapNotify that are caused by us, if
|
/* Number of UnmapNotify that are caused by us, if
|
||||||
|
@ -544,7 +544,7 @@ counter_from_results (GetPropertyResults *results,
|
|||||||
XSyncCounter *counter_p)
|
XSyncCounter *counter_p)
|
||||||
{
|
{
|
||||||
if (!validate_or_free_results (results, 32,
|
if (!validate_or_free_results (results, 32,
|
||||||
results->display->atom_sync_counter,
|
XA_CARDINAL,
|
||||||
TRUE))
|
TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -986,7 +986,7 @@ meta_prop_get_values (MetaDisplay *display,
|
|||||||
values[i].required_type = XA_WM_SIZE_HINTS;
|
values[i].required_type = XA_WM_SIZE_HINTS;
|
||||||
break;
|
break;
|
||||||
case META_PROP_VALUE_SYNC_COUNTER:
|
case META_PROP_VALUE_SYNC_COUNTER:
|
||||||
values[i].required_type = display->atom_sync_counter;
|
values[i].required_type = XA_CARDINAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ typedef enum
|
|||||||
META_PROP_VALUE_WM_HINTS,
|
META_PROP_VALUE_WM_HINTS,
|
||||||
META_PROP_VALUE_CLASS_HINT,
|
META_PROP_VALUE_CLASS_HINT,
|
||||||
META_PROP_VALUE_SIZE_HINTS,
|
META_PROP_VALUE_SIZE_HINTS,
|
||||||
META_PROP_VALUE_SYNC_COUNTER
|
META_PROP_VALUE_SYNC_COUNTER /* comes back as CARDINAL */
|
||||||
} MetaPropValueType;
|
} MetaPropValueType;
|
||||||
|
|
||||||
/* used to request/return/store property values */
|
/* used to request/return/store property values */
|
||||||
|
Loading…
Reference in New Issue
Block a user