summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog31
-rw-r--r--configure.in29
-rw-r--r--src/display.c256
-rw-r--r--src/display.h27
-rw-r--r--src/util.c2
-rw-r--r--src/util.h3
-rw-r--r--src/window-props.c32
-rw-r--r--src/window.c245
-rw-r--r--src/window.h7
-rw-r--r--src/xprops.c32
-rw-r--r--src/xprops.h7
12 files changed, 536 insertions, 136 deletions
diff --git a/AUTHORS b/AUTHORS
index e69de29b..9971ab08 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -0,0 +1 @@
+Havoc Pennington <hp@redhat.com>
diff --git a/ChangeLog b/ChangeLog
index 57d31a44..e03998f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2002-12-09 Havoc Pennington <hp@pobox.com>
+
+ * AUTHORS: add myself here, bug #100789
+
+ * src/display.c (meta_display_set_grab_op_cursor): drop
+ PointerMotionHintMask
+
+ * src/window.c (meta_window_handle_mouse_grab_op_event): don't use
+ XQueryPointer, as we aren't using PointerMotionHint now
+
+ * src/display.c (event_callback): rearrange a bit of code
+ for slight speedup and clarity
+
+ * src/window.c (update_resize)
+ (meta_window_handle_mouse_grab_op_event): implement
+ usage of the _METACITY_UPDATE_COUNTER
+ (meta_window_handle_mouse_grab_op_event): fix code that
+ used event->xbutton with a motion event
+
+ * src/display.c (meta_display_open): add new atoms, and
+ initialize Xsync if we have it
+ (grab_op_is_resizing): new function
+ (meta_display_begin_grab_op): create an alarm monitoring
+ window's _METACITY_UPDATE_COUNTER
+ (meta_spew_event): conditionalize this on WITH_VERBOSE_MODE
+ and print alarm events.
+
+ * src/window.c (meta_window_new): fetch _METACITY_UPDATE_COUNTER
+
+ * configure.in (HAVE_XSYNC): check for Xsync extension
+
Mon Dec 9 22:09:56 2002 Soeren Sandmann <sandmann@daimi.au.dk>
* src/display.c, src/window.c: Handle crossing events during
diff --git a/configure.in b/configure.in
index 9755d6f2..e4665914 100644
--- a/configure.in
+++ b/configure.in
@@ -108,6 +108,8 @@ AC_ARG_ENABLE(sm, [ --disable-sm disable metacity's session m
AC_ARG_ENABLE(startup-notification, [ --disable-startup-notification disable metacity's startup notification support, for embedded/size-sensitive custom non-GNOME builds],enable_startup_notification=no,enable_startup_notification=auto)
+AC_ARG_ENABLE(xsync, [ --disable-xsync disable metacity's use of the XSync extension],enable_xsync=no,enable_xsync=auto)
+
## try definining HAVE_BACKTRACE
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
@@ -231,7 +233,31 @@ if test "x$found_randr" = "xyes"; then
AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library])
fi
-METACITY_LIBS="$RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_LIBS"
+XSYNC_LIBS=
+found_xsync=no
+AC_CHECK_LIB(Xext, XSyncQueryExtension,
+ [AC_CHECK_HEADER(X11/extensions/sync.h,
+ found_xsync=yes,,
+ [#include <X11/Xlib.h>])],
+ , $ALL_X_LIBS)
+
+if test x$enable_xsync = xno; then
+ found_xsync=no
+fi
+
+if test x$enable_xsync = xyes; then
+ if test "$found_xsync" = "no"; then
+ AC_MSG_ERROR([--enable-xsync forced and XSync not found])
+ exit 1
+ fi
+fi
+
+if test "x$found_xsync" = "xyes"; then
+ XSYNC_LIBS=-lXext
+ AC_DEFINE(HAVE_XSYNC, , [Have the Xsync extension library])
+fi
+
+METACITY_LIBS="$XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_LIBS"
METACITY_MESSAGE_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_MESSAGE_LIBS"
METACITY_WINDOW_DEMO_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_WINDOW_DEMO_LIBS"
METACITY_PROPS_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_PROPS_LIBS"
@@ -338,5 +364,6 @@ metacity-$VERSION:
Session management: ${found_sm}
Shape extension: ${found_shape}
Resize-and-rotate: ${found_randr}
+ Xsync: ${found_xsync}
Deprecated config dialog: ${enable_config_dialog}
"
diff --git a/src/display.c b/src/display.c
index 48a1b779..18ea58a5 100644
--- a/src/display.c
+++ b/src/display.c
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2002 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -253,7 +254,9 @@ meta_display_open (const char *name)
"_NET_WM_STATE_ABOVE",
"_NET_WM_STATE_BELOW",
"_NET_STARTUP_ID",
- "_METACITY_TOGGLE_VERBOSE"
+ "_METACITY_TOGGLE_VERBOSE",
+ "_METACITY_UPDATE_COUNTER",
+ "SYNC_COUNTER"
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -389,6 +392,8 @@ meta_display_open (const char *name)
display->atom_net_wm_state_below = atoms[76];
display->atom_net_startup_id = atoms[77];
display->atom_metacity_toggle_verbose = atoms[78];
+ display->atom_metacity_update_counter = atoms[79];
+ display->atom_sync_counter = atoms[80];
display->prop_hooks = NULL;
meta_display_init_window_prop_hooks (display);
@@ -453,6 +458,35 @@ meta_display_open (const char *name)
display->grab_screen = NULL;
display->grab_resize_popup = NULL;
+#ifdef HAVE_XSYNC
+ {
+ int major, minor;
+
+ display->xsync_error_base = 0;
+ display->xsync_event_base = 0;
+
+ /* I don't think we really have to fill these in */
+ major = SYNC_MAJOR_VERSION;
+ minor = SYNC_MINOR_VERSION;
+
+ if (!XSyncQueryExtension (display->xdisplay,
+ &display->xsync_event_base,
+ &display->xsync_error_base) ||
+ !XSyncInitialize (display->xdisplay,
+ &major, &minor))
+ {
+ display->xsync_error_base = 0;
+ display->xsync_event_base = 0;
+ }
+ meta_verbose ("Attempted to init Xsync, found version %d.%d error base %d event base %d\n",
+ major, minor,
+ display->xsync_error_base,
+ display->xsync_event_base);
+ }
+#else /* HAVE_XSYNC */
+ meta_verbose ("Not compiled with Xsync support\n");
+#endif /* !HAVE_XSYNC */
+
screens = NULL;
#ifdef HAVE_GTK_MULTIHEAD
@@ -896,6 +930,51 @@ grab_op_is_keyboard (MetaGrabOp op)
}
}
+gboolean
+meta_grab_op_is_resizing (MetaGrabOp op)
+{
+ switch (op)
+ {
+ case META_GRAB_OP_RESIZING_SE:
+ case META_GRAB_OP_RESIZING_S:
+ case META_GRAB_OP_RESIZING_SW:
+ case META_GRAB_OP_RESIZING_N:
+ case META_GRAB_OP_RESIZING_NE:
+ case META_GRAB_OP_RESIZING_NW:
+ case META_GRAB_OP_RESIZING_W:
+ case META_GRAB_OP_RESIZING_E:
+ case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
+ case META_GRAB_OP_KEYBOARD_RESIZING_S:
+ case META_GRAB_OP_KEYBOARD_RESIZING_N:
+ case META_GRAB_OP_KEYBOARD_RESIZING_W:
+ case META_GRAB_OP_KEYBOARD_RESIZING_E:
+ case META_GRAB_OP_KEYBOARD_RESIZING_SE:
+ case META_GRAB_OP_KEYBOARD_RESIZING_NE:
+ case META_GRAB_OP_KEYBOARD_RESIZING_SW:
+ case META_GRAB_OP_KEYBOARD_RESIZING_NW:
+ return TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+}
+
+gboolean
+meta_grab_op_is_moving (MetaGrabOp op)
+{
+ switch (op)
+ {
+ case META_GRAB_OP_MOVING:
+ case META_GRAB_OP_KEYBOARD_MOVING:
+ return TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+}
+
/* Get time of current event, or CurrentTime if none. */
guint32
meta_display_get_current_time (MetaDisplay *display)
@@ -1093,6 +1172,20 @@ event_callback (XEvent *event,
frame_was_receiver = TRUE;
meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event\n");
}
+
+#ifdef HAVE_XSYNC
+ if (META_DISPLAY_HAS_XSYNC (display) &&
+ event->type == (display->xsync_event_base + XSyncAlarmNotify) &&
+ ((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_update_alarm)
+ {
+ filter_out_event = TRUE; /* GTK doesn't want to see this really */
+
+ if (display->grab_op != META_GRAB_OP_NONE &&
+ display->grab_window != NULL &&
+ grab_op_is_mouse (display->grab_op))
+ meta_window_handle_mouse_grab_op_event (display->grab_window, event);
+ }
+#endif /* HAVE_XSYNC */
switch (event->type)
{
@@ -1242,25 +1335,22 @@ event_callback (XEvent *event,
}
break;
case ButtonRelease:
- if (grab_op_is_mouse (display->grab_op) &&
- display->grab_window == window)
+ if (display->grab_window == window &&
+ grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case MotionNotify:
- if (grab_op_is_mouse (display->grab_op) &&
- display->grab_window == window)
+ if (display->grab_window == window &&
+ grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case EnterNotify:
- if (grab_op_is_mouse (display->grab_op) &&
- display->grab_window == window)
- {
- meta_window_handle_mouse_grab_op_event (window, event);
- break;
- }
+ if (display->grab_window == window &&
+ grab_op_is_mouse (display->grab_op))
+ meta_window_handle_mouse_grab_op_event (window, event);
/* do this even if window->has_focus to avoid races */
- if (window && !serial_is_ignored (display, event->xany.serial) &&
- event->xcrossing.detail != NotifyInferior)
+ else if (window && !serial_is_ignored (display, event->xany.serial) &&
+ event->xcrossing.detail != NotifyInferior)
{
switch (meta_prefs_get_focus_mode ())
{
@@ -1317,13 +1407,10 @@ event_callback (XEvent *event,
}
break;
case LeaveNotify:
- if (grab_op_is_mouse (display->grab_op) &&
- display->grab_window == window)
- {
- meta_window_handle_mouse_grab_op_event (window, event);
- break;
- }
- if (window)
+ if (display->grab_window == window &&
+ grab_op_is_mouse (display->grab_op))
+ meta_window_handle_mouse_grab_op_event (window, event);
+ else if (window != NULL)
{
switch (meta_prefs_get_focus_mode ())
{
@@ -1872,6 +1959,7 @@ event_get_time (MetaDisplay *display,
}
}
+#ifdef WITH_VERBOSE_MODE
const char*
meta_event_detail_to_string (int d)
{
@@ -1908,7 +1996,9 @@ meta_event_detail_to_string (int d)
return detail;
}
+#endif /* WITH_VERBOSE_MODE */
+#ifdef WITH_VERBOSE_MODE
const char*
meta_event_mode_to_string (int m)
{
@@ -1936,7 +2026,9 @@ meta_event_mode_to_string (int m)
return mode;
}
+#endif /* WITH_VERBOSE_MODE */
+#ifdef WITH_VERBOSE_MODE
static const char*
stack_mode_to_string (int mode)
{
@@ -1956,7 +2048,9 @@ stack_mode_to_string (int mode)
return "Unknown";
}
+#endif /* WITH_VERBOSE_MODE */
+#ifdef WITH_VERBOSE_MODE
static char*
key_event_description (Display *xdisplay,
XEvent *event)
@@ -1971,7 +2065,43 @@ key_event_description (Display *xdisplay,
return g_strdup_printf ("Key '%s' state 0x%x",
str ? str : "(null)", event->xkey.state);
}
+#endif /* WITH_VERBOSE_MODE */
+
+#ifdef HAVE_XSYNC
+#ifdef WITH_VERBOSE_MODE
+static gint64
+sync_value_to_64 (const XSyncValue *value)
+{
+ gint64 v;
+
+ v = XSyncValueLow32 (*value);
+ v |= (((gint64)XSyncValueHigh32 (*value)) << 32);
+
+ return v;
+}
+#endif /* WITH_VERBOSE_MODE */
+
+#ifdef WITH_VERBOSE_MODE
+static const char*
+alarm_state_to_string (XSyncAlarmState state)
+{
+ switch (state)
+ {
+ case XSyncAlarmActive:
+ return "Active";
+ case XSyncAlarmInactive:
+ return "Inactive";
+ case XSyncAlarmDestroyed:
+ return "Destroyed";
+ default:
+ return "(unknown)";
+ }
+}
+#endif /* WITH_VERBOSE_MODE */
+
+#endif /* HAVE_XSYNC */
+#ifdef WITH_VERBOSE_MODE
static void
meta_spew_event (MetaDisplay *display,
XEvent *event)
@@ -2207,8 +2337,30 @@ meta_spew_event (MetaDisplay *display,
name = "MappingNotify";
break;
default:
- name = "(Unknown event)";
- extra = g_strdup_printf ("type: %d", event->xany.type);
+#ifdef HAVE_XSYNC
+ if (META_DISPLAY_HAS_XSYNC (display) &&
+ event->type == (display->xsync_event_base + XSyncAlarmNotify))
+ {
+ XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event;
+
+ name = "XSyncAlarmNotify";
+ extra =
+ g_strdup_printf ("alarm: 0x%lx"
+ " counter_value: %" G_GINT64_FORMAT
+ " alarm_value: %" G_GINT64_FORMAT
+ " time: %u alarm state: %s",
+ aevent->alarm,
+ (gint64) sync_value_to_64 (&aevent->counter_value),
+ (gint64) sync_value_to_64 (&aevent->alarm_value),
+ (unsigned int) aevent->time,
+ alarm_state_to_string (aevent->state));
+ }
+ else
+#endif /* HAVE_XSYNC */
+ {
+ name = "(Unknown event)";
+ extra = g_strdup_printf ("type: %d", event->xany.type);
+ }
break;
}
@@ -2230,6 +2382,7 @@ meta_spew_event (MetaDisplay *display,
if (extra)
g_free (extra);
}
+#endif /* WITH_VERBOSE_MODE */
MetaWindow*
meta_display_lookup_x_window (MetaDisplay *display,
@@ -2385,8 +2538,8 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
cursor = xcursor_for_op (display, op);
-#define GRAB_MASK (PointerMotionMask | PointerMotionHintMask | \
- ButtonPressMask | ButtonReleaseMask | \
+#define GRAB_MASK (PointerMotionMask | \
+ ButtonPressMask | ButtonReleaseMask | \
EnterWindowMask | LeaveWindowMask)
if (change_pointer)
@@ -2515,9 +2668,14 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_initial_root_y = root_y;
display->grab_current_root_x = root_x;
display->grab_current_root_y = root_y;
+ display->grab_latest_motion_x = root_x;
+ display->grab_latest_motion_y = root_y;
display->grab_last_moveresize_time.tv_sec = 0;
display->grab_last_moveresize_time.tv_usec = 0;
-
+#ifdef HAVE_XSYNC
+ display->grab_update_alarm = None;
+#endif
+
if (display->grab_window)
{
display->grab_initial_window_pos = display->grab_window->rect;
@@ -2525,6 +2683,46 @@ meta_display_begin_grab_op (MetaDisplay *display,
&display->grab_initial_window_pos.x,
&display->grab_initial_window_pos.y);
display->grab_current_window_pos = display->grab_initial_window_pos;
+
+#ifdef HAVE_XSYNC
+ if (meta_grab_op_is_resizing (display->grab_op) &&
+ display->grab_window->update_counter != None)
+ {
+ XSyncAlarmAttributes values;
+
+ /* 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;
+ values.trigger.test_type = XSyncPositiveTransition;
+ XSyncIntToValue (&values.trigger.wait_value, 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,
+ XSyncCACounter |
+ XSyncCAValueType |
+ XSyncCAValue |
+ XSyncCATestType |
+ XSyncCADelta |
+ XSyncCAEvents,
+ &values);
+ if (meta_error_trap_pop_with_return (display, FALSE) != Success)
+ display->grab_update_alarm = None;
+
+ meta_topic (META_DEBUG_RESIZING,
+ "Created update alarm 0x%lx\n",
+ display->grab_update_alarm);
+ }
+#endif
}
meta_topic (META_DEBUG_WINDOW_OPS,
@@ -2604,6 +2802,14 @@ meta_display_end_grab_op (MetaDisplay *display,
else
meta_screen_ungrab_all_keys (display->grab_screen);
}
+
+#ifdef HAVE_XSYNC
+ if (display->grab_update_alarm != None)
+ {
+ XSyncDestroyAlarm (display->xdisplay,
+ display->grab_update_alarm);
+ }
+#endif /* HAVE_XSYNC */
display->grab_window = NULL;
display->grab_screen = NULL;
diff --git a/src/display.h b/src/display.h
index efd125ca..2641af4d 100644
--- a/src/display.h
+++ b/src/display.h
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2002 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -35,6 +36,10 @@
#include <libsn/sn.h>
#endif
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
/* this doesn't really belong here, oh well. */
@@ -162,6 +167,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;
/* This is the actual window from focus events,
* not the one we last set
@@ -229,6 +236,8 @@ struct _MetaDisplay
int grab_initial_root_y;
int grab_current_root_x;
int grab_current_root_y;
+ int grab_latest_motion_x;
+ int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
@@ -236,7 +245,10 @@ struct _MetaDisplay
MetaRectangle grab_current_window_pos;
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
-
+#ifdef HAVE_XSYNC
+ /* alarm monitoring client's _METACITY_UPDATE_COUNTER */
+ XSyncAlarm grab_update_alarm;
+#endif
/* Keybindings stuff */
MetaKeyBinding *screen_bindings;
@@ -275,11 +287,15 @@ struct _MetaDisplay
MetaGroupPropHooks *group_prop_hooks;
#ifdef HAVE_STARTUP_NOTIFICATION
- /* This is at the end in case someone doesn't include config.h before this file
- * the results won't be catastrophic
- */
SnDisplay *sn_display;
#endif
+#ifdef HAVE_XSYNC
+ int xsync_event_base;
+ int xsync_error_base;
+#define META_DISPLAY_HAS_XSYNC(display) ((display)->xsync_event_base != 0)
+#else
+#define META_DISPLAY_HAS_XSYNC(display) FALSE
+#endif
};
gboolean meta_display_open (const char *name);
@@ -399,6 +415,9 @@ MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
int meta_resize_gravity_from_grab_op (MetaGrabOp op);
+gboolean meta_grab_op_is_moving (MetaGrabOp op);
+gboolean meta_grab_op_is_resizing (MetaGrabOp op);
+
gboolean meta_rectangle_intersect (MetaRectangle *src1,
MetaRectangle *src2,
MetaRectangle *dest);
diff --git a/src/util.c b/src/util.c
index 1d754422..b54a66ce 100644
--- a/src/util.c
+++ b/src/util.c
@@ -280,6 +280,8 @@ topic_name (MetaDebugTopic topic)
return "PREFS";
case META_DEBUG_GROUPS:
return "GROUPS";
+ case META_DEBUG_RESIZING:
+ return "RESIZING";
}
return "Window manager";
diff --git a/src/util.h b/src/util.h
index 280e7eed..abf29ea1 100644
--- a/src/util.h
+++ b/src/util.h
@@ -64,7 +64,8 @@ typedef enum
META_DEBUG_ERRORS = 1 << 14,
META_DEBUG_STARTUP = 1 << 15,
META_DEBUG_PREFS = 1 << 16,
- META_DEBUG_GROUPS = 1 << 17
+ META_DEBUG_GROUPS = 1 << 17,
+ META_DEBUG_RESIZING = 1 << 18
} MetaDebugTopic;
diff --git a/src/window-props.c b/src/window-props.c
index f1d19ce6..bcf63981 100644
--- a/src/window-props.c
+++ b/src/window-props.c
@@ -412,7 +412,32 @@ reload_net_startup_id (MetaWindow *window,
window->desc);
}
-#define N_HOOKS 23
+static void
+init_update_counter (MetaDisplay *display,
+ Atom property,
+ MetaPropValue *value)
+{
+ value->type = META_PROP_VALUE_SYNC_COUNTER;
+ value->atom = display->atom_metacity_update_counter;
+}
+
+static void
+reload_update_counter (MetaWindow *window,
+ MetaPropValue *value)
+{
+ if (value->type != META_PROP_VALUE_INVALID)
+ {
+#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);
+#endif
+ }
+}
+
+#define N_HOOKS 24
void
meta_display_init_window_prop_hooks (MetaDisplay *display)
@@ -541,6 +566,11 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
hooks[i].init_func = init_net_startup_id;
hooks[i].reload_func = reload_net_startup_id;
++i;
+
+ hooks[i].property = display->atom_metacity_update_counter;
+ hooks[i].init_func = init_update_counter;
+ hooks[i].reload_func = reload_update_counter;
+ ++i;
if (i != N_HOOKS)
g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS);
diff --git a/src/window.c b/src/window.c
index b5ac0157..a79e6001 100644
--- a/src/window.c
+++ b/src/window.c
@@ -159,7 +159,7 @@ meta_window_new (MetaDisplay *display,
GSList *tmp;
MetaWorkspace *space;
gulong existing_wm_state;
-#define N_INITIAL_PROPS 9
+#define N_INITIAL_PROPS 10
Atom initial_props[N_INITIAL_PROPS];
int i;
@@ -280,12 +280,16 @@ meta_window_new (MetaDisplay *display,
window->dialog_pipe = -1;
window->xwindow = xwindow;
-
+
/* this is in window->screen->display, but that's too annoying to
* type
*/
window->display = display;
window->workspaces = NULL;
+
+#ifdef HAVE_XSYNC
+ window->update_counter = None;
+#endif
window->screen = NULL;
tmp = display->screens;
@@ -443,6 +447,7 @@ meta_window_new (MetaDisplay *display,
initial_props[i++] = display->atom_net_wm_desktop;
initial_props[i++] = display->atom_win_workspace;
initial_props[i++] = display->atom_net_startup_id;
+ initial_props[i++] = display->atom_metacity_update_counter;
g_assert (N_INITIAL_PROPS == i);
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
@@ -4138,6 +4143,13 @@ 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)
+ {
+ meta_verbose ("Property notify on %s for _METACITY_UPDATE_COUNTER\n", window->desc);
+
+ meta_window_reload_property (window,
+ window->display->atom_metacity_update_counter);
+ }
return TRUE;
}
@@ -6064,37 +6076,6 @@ meta_window_show_menu (MetaWindow *window,
meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
}
-static gboolean
-window_query_root_pointer (MetaWindow *window,
- int *x, int *y)
-{
- Window root_return, child_return;
- int root_x_return, root_y_return;
- int win_x_return, win_y_return;
- unsigned int mask_return;
-
- meta_error_trap_push (window->display);
-
- XQueryPointer (window->display->xdisplay,
- window->xwindow,
- &root_return,
- &child_return,
- &root_x_return,
- &root_y_return,
- &win_x_return,
- &win_y_return,
- &mask_return);
-
- meta_error_trap_pop (window->display, TRUE);
-
- if (x)
- *x = root_x_return;
- if (y)
- *y = root_y_return;
-
- return root_return == window->screen->xroot;
-}
-
static void
clear_moveresize_time (MetaWindow *window)
{
@@ -6108,6 +6089,7 @@ check_moveresize_frequency (MetaWindow *window)
{
GTimeVal current_time;
double elapsed;
+ double max_resizes_per_second;
g_get_current_time (&current_time);
@@ -6116,12 +6098,24 @@ check_moveresize_frequency (MetaWindow *window)
((((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;
-#define EPSILON (1e-6)
-#define MAX_RESIZES_PER_SECOND 20.0
- if (elapsed >= 0.0 && elapsed < (1000.0 / MAX_RESIZES_PER_SECOND))
+#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.
+ */
+ 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_verbose ("Delaying move/resize as only %g of %g seconds elapsed\n",
- elapsed / 1000.0, 1.0 / MAX_RESIZES_PER_SECOND);
+ 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;
}
else if (elapsed < (0.0 - EPSILON)) /* handle clock getting set backward */
@@ -6129,9 +6123,10 @@ check_moveresize_frequency (MetaWindow *window)
/* store latest time */
window->display->grab_last_moveresize_time = current_time;
-
- meta_verbose ("Doing move/resize as %g of %g seconds elapsed\n",
- elapsed / 1000.0, 1.0 / MAX_RESIZES_PER_SECOND);
+
+ meta_topic (META_DEBUG_RESIZING,
+ " Doing move/resize now (%g of %g seconds elapsed)\n",
+ elapsed / 1000.0, 1.0 / max_resizes_per_second);
return TRUE;
}
@@ -6144,6 +6139,10 @@ update_move (MetaWindow *window,
{
int dx, dy;
int new_x, new_y;
+ int move_threshold;
+
+ window->display->grab_latest_motion_x = x;
+ window->display->grab_latest_motion_y = y;
dx = x - window->display->grab_current_root_x;
dy = y - window->display->grab_current_root_y;
@@ -6161,9 +6160,14 @@ update_move (MetaWindow *window,
/* Force a move regardless of time if a certain delta is exceeded,
* so we don't get too out of sync with reality when dropping frames
*/
-#define MOVE_THRESHOLD 20
+ /* FIXME this delta is all wrong, as it's absolute since
+ * the grab started. We want some sort of delta since
+ * we last sent a configure or something.
+ */
+ move_threshold = 30;
+
if (!check_moveresize_frequency (window) &&
- ABS (dx) < MOVE_THRESHOLD && ABS (dy) < MOVE_THRESHOLD)
+ ABS (dx) < move_threshold && ABS (dy) < move_threshold)
return;
meta_window_move (window, TRUE, new_x, new_y);
@@ -6176,6 +6180,11 @@ update_resize (MetaWindow *window,
int dx, dy;
int new_w, new_h;
int gravity;
+ int resize_threshold;
+ MetaRectangle old;
+
+ window->display->grab_latest_motion_x = x;
+ window->display->grab_latest_motion_y = y;
dx = x - window->display->grab_current_root_x;
dy = y - window->display->grab_current_root_y;
@@ -6232,36 +6241,54 @@ update_resize (MetaWindow *window,
/* Force a move regardless of time if a certain delta
* is exceeded
+ * FIXME this delta is all wrong, as it's absolute since
+ * the grab started. We want some sort of delta since
+ * we last sent a configure or something.
*/
-#define RESIZE_THRESHOLD 20
+#ifdef HAVE_XSYNC
+ if (window->display->grab_update_alarm != None)
+ resize_threshold = 5000; /* disable */
+ else
+#endif /* HAVE_XSYNC */
+ resize_threshold = 30;
+
if (!check_moveresize_frequency (window) &&
- ABS (dx) < RESIZE_THRESHOLD && ABS (dy) < RESIZE_THRESHOLD)
+ ABS (dx) < resize_threshold && ABS (dy) < resize_threshold)
return;
+
+ old = window->rect;
/* compute gravity of client during operation */
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
g_assert (gravity >= 0);
-
+
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);
}
void
meta_window_handle_mouse_grab_op_event (MetaWindow *window,
XEvent *event)
{
- switch (event->type)
+#ifdef HAVE_XSYNC
+ if (event->type == (window->display->xsync_event_base + XSyncAlarmNotify))
{
- case ButtonRelease:
+ 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);
+
+ /* This means we are ready for another configure. */
switch (window->display->grab_op)
{
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_KEYBOARD_MOVING:
- 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);
- break;
-
case META_GRAB_OP_RESIZING_E:
case META_GRAB_OP_RESIZING_W:
case META_GRAB_OP_RESIZING_S:
@@ -6278,62 +6305,76 @@ 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);
- if (event->xbutton.root == window->screen->xroot)
- update_resize (window, event->xbutton.x_root, event->xbutton.y_root);
- break;
+ 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);
+ break;
+
default:
break;
}
+ }
+#endif /* HAVE_XSYNC */
+
+ switch (event->type)
+ {
+ 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);
+ }
meta_display_end_grab_op (window->display, event->xbutton.time);
+ break;
+
+ case MotionNotify:
+ if (meta_grab_op_is_moving (window->display->grab_op))
+ {
+ if (event->xmotion.root == window->screen->xroot)
+ update_move (window,
+ event->xmotion.state,
+ event->xmotion.x_root,
+ event->xmotion.y_root);
+ }
+ else if (meta_grab_op_is_resizing (window->display->grab_op))
+ {
+ if (event->xmotion.root == window->screen->xroot)
+ update_resize (window,
+ event->xmotion.x_root,
+ event->xmotion.y_root);
+ }
break;
-
+
case EnterNotify:
case LeaveNotify:
- case MotionNotify:
- switch (window->display->grab_op)
+ if (meta_grab_op_is_moving (window->display->grab_op))
{
- case META_GRAB_OP_MOVING:
- case META_GRAB_OP_KEYBOARD_MOVING:
- {
- int x, y;
- if (window_query_root_pointer (window, &x, &y))
- update_move (window,
- event->xbutton.state,
- x, y);
- }
- break;
-
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_RESIZING_SE:
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- {
- int x, y;
- if (window_query_root_pointer (window, &x, &y))
- update_resize (window, x, y);
- }
- break;
-
- default:
- break;
+ if (event->xcrossing.root == window->screen->xroot)
+ update_move (window,
+ event->xcrossing.state,
+ event->xcrossing.x_root,
+ event->xcrossing.y_root);
+ }
+ else if (meta_grab_op_is_resizing (window->display->grab_op))
+ {
+ if (event->xcrossing.root == window->screen->xroot)
+ update_resize (window,
+ event->xcrossing.x_root,
+ event->xcrossing.y_root);
}
break;
-
default:
break;
}
@@ -6711,9 +6752,7 @@ meta_window_update_resize_grab_op (MetaWindow *window,
window->display->grab_current_root_y = y + y_offset;
if (window->display->grab_window)
- {
- window->display->grab_current_window_pos = window->rect;
- }
+ window->display->grab_current_window_pos = window->rect;
if (update_cursor)
{
diff --git a/src/window.h b/src/window.h
index 21c71179..c200c9c8 100644
--- a/src/window.h
+++ b/src/window.h
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2002 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -22,6 +23,7 @@
#ifndef META_WINDOW_H
#define META_WINDOW_H
+#include <config.h>
#include "screen.h"
#include "util.h"
#include "stack.h"
@@ -216,6 +218,11 @@ struct _MetaWindow
/* Info on which props we got our attributes from */
guint using_net_wm_name : 1; /* vs. plain wm_name */
guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */
+
+#ifdef HAVE_XSYNC
+ /* XSync update counter */
+ XSyncCounter update_counter;
+#endif
/* Number of UnmapNotify that are caused by us, if
* we get UnmapNotify with none pending then the client
diff --git a/src/xprops.c b/src/xprops.c
index 4f92e2d4..f903b1e6 100644
--- a/src/xprops.c
+++ b/src/xprops.c
@@ -505,6 +505,24 @@ window_from_results (GetPropertyResults *results,
return TRUE;
}
+#ifdef HAVE_XSYNC
+static gboolean
+counter_from_results (GetPropertyResults *results,
+ XSyncCounter *counter_p)
+{
+ if (!validate_or_free_results (results, 32,
+ results->display->atom_sync_counter,
+ TRUE))
+ return FALSE;
+
+ *counter_p = *(XSyncCounter*) results->prop;
+ XFree (results->prop);
+ results->prop = NULL;
+
+ return TRUE;
+}
+#endif
+
gboolean
meta_prop_get_window (MetaDisplay *display,
Window xwindow,
@@ -915,6 +933,9 @@ meta_prop_get_values (MetaDisplay *display,
case META_PROP_VALUE_SIZE_HINTS:
values[i].required_type = XA_WM_SIZE_HINTS;
break;
+ case META_PROP_VALUE_SYNC_COUNTER:
+ values[i].required_type = display->atom_sync_counter;
+ break;
}
}
@@ -1042,6 +1063,15 @@ meta_prop_get_values (MetaDisplay *display,
&values[i].v.size_hints.flags))
values[i].type = META_PROP_VALUE_INVALID;
break;
+ case META_PROP_VALUE_SYNC_COUNTER:
+#ifdef HAVE_XSYNC
+ if (!counter_from_results (&results,
+ &values[i].v.xcounter))
+ values[i].type = META_PROP_VALUE_INVALID;
+#else
+ values[i].type = META_PROP_VALUE_INVALID;
+#endif
+ break;
}
next:
@@ -1093,6 +1123,8 @@ free_value (MetaPropValue *value)
case META_PROP_VALUE_CARDINAL_LIST:
meta_XFree (value->v.cardinal_list.cardinals);
break;
+ case META_PROP_VALUE_SYNC_COUNTER:
+ break;
}
}
diff --git a/src/xprops.h b/src/xprops.h
index a1c6adfd..24180ee6 100644
--- a/src/xprops.h
+++ b/src/xprops.h
@@ -22,6 +22,7 @@
#ifndef META_XPROPS_H
#define META_XPROPS_H
+#include <config.h>
#include "display.h"
#include <X11/Xutil.h>
@@ -142,7 +143,8 @@ typedef enum
META_PROP_VALUE_TEXT_PROPERTY, /* comes back as UTF-8 string */
META_PROP_VALUE_WM_HINTS,
META_PROP_VALUE_CLASS_HINT,
- META_PROP_VALUE_SIZE_HINTS
+ META_PROP_VALUE_SIZE_HINTS,
+ META_PROP_VALUE_SYNC_COUNTER
} MetaPropValueType;
/* used to request/return/store property values */
@@ -160,6 +162,9 @@ typedef struct
gulong cardinal;
XWMHints *wm_hints;
XClassHint class_hint;
+#ifdef HAVE_XSYNC
+ XSyncCounter xcounter;
+#endif
struct
{