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>
|
||||
|
||||
* configure.in: bump version, add the UNSTABLE note
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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_STARTUP_ID",
|
||||
"_METACITY_TOGGLE_VERBOSE",
|
||||
"_METACITY_UPDATE_COUNTER",
|
||||
"SYNC_COUNTER",
|
||||
"_NET_WM_SYNC_REQUEST",
|
||||
"_NET_WM_SYNC_REQUEST_COUNTER",
|
||||
"_GNOME_PANEL_ACTION",
|
||||
"_GNOME_PANEL_ACTION_MAIN_MENU",
|
||||
"_GNOME_PANEL_ACTION_RUN_DIALOG",
|
||||
@ -323,7 +323,7 @@ meta_display_open (const char *name)
|
||||
display->expected_focus_window = NULL;
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
display->grab_update_alarm = None;
|
||||
display->grab_sync_request_alarm = None;
|
||||
#endif
|
||||
|
||||
/* 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_startup_id = atoms[72];
|
||||
display->atom_metacity_toggle_verbose = atoms[73];
|
||||
display->atom_metacity_update_counter = atoms[74];
|
||||
display->atom_sync_counter = atoms[75];
|
||||
display->atom_net_wm_sync_request = atoms[74];
|
||||
display->atom_net_wm_sync_request_counter = atoms[75];
|
||||
display->atom_gnome_panel_action = atoms[76];
|
||||
display->atom_gnome_panel_action_main_menu = atoms[77];
|
||||
display->atom_gnome_panel_action_run_dialog = atoms[78];
|
||||
@ -1264,7 +1264,7 @@ 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_update_alarm)
|
||||
((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
|
||||
{
|
||||
filter_out_event = TRUE; /* GTK doesn't want to see this really */
|
||||
|
||||
@ -1272,7 +1272,7 @@ event_callback (XEvent *event,
|
||||
display->grab_window != NULL &&
|
||||
event->xany.serial >= display->grab_start_serial &&
|
||||
grab_op_is_mouse (display->grab_op))
|
||||
meta_window_handle_mouse_grab_op_event (display->grab_window, event);
|
||||
meta_window_handle_mouse_grab_op_event (display->grab_window, event);
|
||||
}
|
||||
#endif /* HAVE_XSYNC */
|
||||
|
||||
@ -2969,10 +2969,16 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
display->grab_last_moveresize_time.tv_usec = 0;
|
||||
display->grab_motion_notify_time = 0;
|
||||
#ifdef HAVE_XSYNC
|
||||
display->grab_update_alarm = None;
|
||||
display->grab_sync_request_alarm = None;
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
display->grab_initial_window_pos = display->grab_window->rect;
|
||||
@ -3007,28 +3013,41 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
#ifdef HAVE_XSYNC
|
||||
if (!display->grab_wireframe_active &&
|
||||
meta_grab_op_is_resizing (display->grab_op) &&
|
||||
display->grab_window->update_counter != None)
|
||||
display->grab_window->sync_request_counter != None)
|
||||
{
|
||||
XSyncAlarmAttributes values;
|
||||
XSyncValue init;
|
||||
|
||||
/* trigger when we make a positive transition to a value
|
||||
* one higher than the current value.
|
||||
*/
|
||||
values.trigger.counter = display->grab_window->update_counter;
|
||||
values.trigger.value_type = XSyncRelative;
|
||||
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, 1);
|
||||
|
||||
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;
|
||||
|
||||
meta_error_trap_push_with_return (display);
|
||||
display->grab_update_alarm = XSyncCreateAlarm (display->xdisplay,
|
||||
display->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay,
|
||||
XSyncCACounter |
|
||||
XSyncCAValueType |
|
||||
XSyncCAValue |
|
||||
@ -3036,12 +3055,13 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
XSyncCADelta |
|
||||
XSyncCAEvents,
|
||||
&values);
|
||||
|
||||
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,
|
||||
"Created update alarm 0x%lx\n",
|
||||
display->grab_update_alarm);
|
||||
display->grab_sync_request_alarm);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -3138,10 +3158,11 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
}
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
if (display->grab_update_alarm != None)
|
||||
if (display->grab_sync_request_alarm != None)
|
||||
{
|
||||
XSyncDestroyAlarm (display->xdisplay,
|
||||
display->grab_update_alarm);
|
||||
display->grab_sync_request_alarm);
|
||||
display->grab_sync_request_alarm = None;
|
||||
}
|
||||
#endif /* HAVE_XSYNC */
|
||||
|
||||
@ -3177,6 +3198,12 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_ui_resize_popup_free (display->grab_resize_popup);
|
||||
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
|
||||
|
@ -166,8 +166,8 @@ struct _MetaDisplay
|
||||
Atom atom_net_wm_state_below;
|
||||
Atom atom_net_startup_id;
|
||||
Atom atom_metacity_toggle_verbose;
|
||||
Atom atom_metacity_update_counter;
|
||||
Atom atom_sync_counter;
|
||||
Atom atom_net_wm_sync_request;
|
||||
Atom atom_net_wm_sync_request_counter;
|
||||
Atom atom_gnome_panel_action;
|
||||
Atom atom_gnome_panel_action_main_menu;
|
||||
Atom atom_gnome_panel_action_run_dialog;
|
||||
@ -258,9 +258,10 @@ struct _MetaDisplay
|
||||
int xkb_base_event_type;
|
||||
#endif
|
||||
#ifdef HAVE_XSYNC
|
||||
/* alarm monitoring client's _METACITY_UPDATE_COUNTER */
|
||||
XSyncAlarm grab_update_alarm;
|
||||
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
|
||||
XSyncAlarm grab_sync_request_alarm;
|
||||
#endif
|
||||
int grab_resize_timeout_id;
|
||||
|
||||
/* Keybindings stuff */
|
||||
MetaKeyBinding *screen_bindings;
|
||||
|
@ -385,7 +385,7 @@ init_update_counter (MetaDisplay *display,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
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
|
||||
@ -397,9 +397,9 @@ reload_update_counter (MetaWindow *window,
|
||||
#ifdef HAVE_XSYNC
|
||||
XSyncCounter counter = value->v.xcounter;
|
||||
|
||||
window->update_counter = counter;
|
||||
meta_verbose ("Window has _METACITY_UPDATE_COUNTER 0x%lx\n",
|
||||
window->update_counter);
|
||||
window->sync_request_counter = counter;
|
||||
meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx\n",
|
||||
window->sync_request_counter);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -924,7 +924,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
hooks[i].reload_func = reload_net_startup_id;
|
||||
++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].reload_func = reload_update_counter;
|
||||
++i;
|
||||
|
250
src/window.c
250
src/window.c
@ -357,7 +357,10 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
window->workspaces = NULL;
|
||||
|
||||
#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
|
||||
|
||||
window->screen = NULL;
|
||||
@ -446,6 +449,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
window->calc_placement = FALSE;
|
||||
window->shaken_loose = FALSE;
|
||||
window->have_focus_click_grab = FALSE;
|
||||
window->disable_sync = FALSE;
|
||||
|
||||
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++] = display->atom_net_wm_desktop;
|
||||
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++] = display->atom_wm_protocols;
|
||||
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
|
||||
meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
@ -2627,10 +2661,20 @@ 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 &&
|
||||
window->sync_request_time.tv_usec == 0 &&
|
||||
window->sync_request_time.tv_sec == 0)
|
||||
{
|
||||
send_sync_request (window);
|
||||
}
|
||||
|
||||
XConfigureWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
mask,
|
||||
&values);
|
||||
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
}
|
||||
|
||||
@ -4364,12 +4408,12 @@ process_property_notify (MetaWindow *window,
|
||||
meta_window_reload_property (window,
|
||||
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,
|
||||
window->display->atom_metacity_update_counter);
|
||||
window->display->atom_net_wm_sync_request_counter);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -5802,59 +5846,94 @@ meta_window_show_menu (MetaWindow *window,
|
||||
meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_moveresize_time (MetaWindow *window)
|
||||
static double
|
||||
timeval_to_ms (const GTimeVal *timeval)
|
||||
{
|
||||
/* Forces the next update to actually do something */
|
||||
window->display->grab_last_moveresize_time.tv_sec = 0;
|
||||
window->display->grab_last_moveresize_time.tv_usec = 0;
|
||||
return (timeval->tv_sec * G_USEC_PER_SEC + timeval->tv_usec) / 1000.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
|
||||
check_moveresize_frequency (MetaWindow *window)
|
||||
check_moveresize_frequency (MetaWindow *window,
|
||||
gdouble *remaining)
|
||||
{
|
||||
GTimeVal current_time;
|
||||
double elapsed;
|
||||
double max_resizes_per_second;
|
||||
|
||||
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
|
||||
if (window->display->grab_update_alarm != None)
|
||||
max_resizes_per_second = 1.0; /* this is max resizes without
|
||||
* getting any alarms; we resize
|
||||
* immediately if we get one.
|
||||
* i.e. this is a timeout for the
|
||||
* client getting stuck.
|
||||
*/
|
||||
if (!window->disable_sync &&
|
||||
window->display->grab_sync_request_alarm != None)
|
||||
{
|
||||
if (window->sync_request_time.tv_sec != 0 ||
|
||||
window->sync_request_time.tv_usec != 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 */
|
||||
max_resizes_per_second = 20.0;
|
||||
|
||||
#define EPSILON (1e-6)
|
||||
if (elapsed >= 0.0 && elapsed < (1000.0 / max_resizes_per_second))
|
||||
{
|
||||
const double max_resizes_per_second = 25.0;
|
||||
const double ms_between_resizes = 1000.0 / max_resizes_per_second;
|
||||
double elapsed;
|
||||
|
||||
elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_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,
|
||||
"Delaying move/resize as only %g of %g seconds elapsed\n",
|
||||
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
||||
return FALSE;
|
||||
" Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
|
||||
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (elapsed < (0.0 - EPSILON)) /* handle clock getting set backward */
|
||||
clear_moveresize_time (window);
|
||||
|
||||
/* store latest time */
|
||||
window->display->grab_last_moveresize_time = current_time;
|
||||
|
||||
meta_topic (META_DEBUG_RESIZING,
|
||||
" Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
|
||||
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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
|
||||
update_resize (MetaWindow *window,
|
||||
int x, int y)
|
||||
int x, int y,
|
||||
gboolean force)
|
||||
{
|
||||
int dx, dy;
|
||||
int new_w, new_h;
|
||||
int gravity;
|
||||
MetaRectangle old;
|
||||
int new_x, new_y;
|
||||
double remaining;
|
||||
|
||||
window->display->grab_latest_motion_x = x;
|
||||
window->display->grab_latest_motion_y = y;
|
||||
@ -6077,8 +6175,28 @@ update_resize (MetaWindow *window,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!check_moveresize_frequency (window))
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -6118,14 +6236,12 @@ update_resize (MetaWindow *window,
|
||||
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
}
|
||||
|
||||
/* If we don't actually resize the window, we clear the timestamp,
|
||||
* so we'll quickly try again. Otherwise you get "stuck" because
|
||||
* the window doesn't increment its _METACITY_UPDATE_COUNTER when
|
||||
* nothing happens.
|
||||
*/
|
||||
if (window->rect.width == old.width &&
|
||||
window->rect.height == old.height)
|
||||
clear_moveresize_time (window);
|
||||
/* Store the latest resize time, if we actually resized. */
|
||||
if (window->rect.width != old.width &&
|
||||
window->rect.height != old.height)
|
||||
{
|
||||
g_get_current_time (&window->display->grab_last_moveresize_time);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@ -6216,6 +6332,14 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
"Alarm event received last motion x = %d y = %d\n",
|
||||
window->display->grab_latest_motion_x,
|
||||
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. */
|
||||
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_SW:
|
||||
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 */
|
||||
update_resize (window,
|
||||
window->display->grab_latest_motion_x,
|
||||
window->display->grab_latest_motion_y);
|
||||
window->display->grab_latest_motion_y,
|
||||
TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -6255,16 +6378,17 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
case ButtonRelease:
|
||||
if (meta_grab_op_is_moving (window->display->grab_op))
|
||||
{
|
||||
clear_moveresize_time (window);
|
||||
if (event->xbutton.root == window->screen->xroot)
|
||||
update_move (window, event->xbutton.state,
|
||||
event->xbutton.x_root, event->xbutton.y_root);
|
||||
}
|
||||
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
||||
{
|
||||
clear_moveresize_time (window);
|
||||
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);
|
||||
@ -6291,7 +6415,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
event))
|
||||
update_resize (window,
|
||||
event->xmotion.x_root,
|
||||
event->xmotion.y_root);
|
||||
event->xmotion.y_root,
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -6311,7 +6436,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
if (event->xcrossing.root == window->screen->xroot)
|
||||
update_resize (window,
|
||||
event->xcrossing.x_root,
|
||||
event->xcrossing.y_root);
|
||||
event->xcrossing.y_root,
|
||||
FALSE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -243,10 +243,15 @@ 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;
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
/* XSync update counter */
|
||||
XSyncCounter update_counter;
|
||||
XSyncCounter sync_request_counter;
|
||||
guint sync_request_serial;
|
||||
GTimeVal sync_request_time;
|
||||
#endif
|
||||
|
||||
/* Number of UnmapNotify that are caused by us, if
|
||||
|
@ -544,7 +544,7 @@ counter_from_results (GetPropertyResults *results,
|
||||
XSyncCounter *counter_p)
|
||||
{
|
||||
if (!validate_or_free_results (results, 32,
|
||||
results->display->atom_sync_counter,
|
||||
XA_CARDINAL,
|
||||
TRUE))
|
||||
return FALSE;
|
||||
|
||||
@ -986,7 +986,7 @@ meta_prop_get_values (MetaDisplay *display,
|
||||
values[i].required_type = XA_WM_SIZE_HINTS;
|
||||
break;
|
||||
case META_PROP_VALUE_SYNC_COUNTER:
|
||||
values[i].required_type = display->atom_sync_counter;
|
||||
values[i].required_type = XA_CARDINAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ typedef enum
|
||||
META_PROP_VALUE_WM_HINTS,
|
||||
META_PROP_VALUE_CLASS_HINT,
|
||||
META_PROP_VALUE_SIZE_HINTS,
|
||||
META_PROP_VALUE_SYNC_COUNTER
|
||||
META_PROP_VALUE_SYNC_COUNTER /* comes back as CARDINAL */
|
||||
} MetaPropValueType;
|
||||
|
||||
/* used to request/return/store property values */
|
||||
|
Loading…
Reference in New Issue
Block a user