add myself here, bug #100789

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
This commit is contained in:
Havoc Pennington 2002-12-10 03:23:04 +00:00 committed by Havoc Pennington
parent ba18c630b7
commit 967777b965
12 changed files with 548 additions and 148 deletions

View File

@ -0,0 +1 @@
Havoc Pennington <hp@redhat.com>

View File

@ -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> Mon Dec 9 22:09:56 2002 Soeren Sandmann <sandmann@daimi.au.dk>
* src/display.c, src/window.c: Handle crossing events during * src/display.c, src/window.c: Handle crossing events during

View File

@ -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(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 ## try definining HAVE_BACKTRACE
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(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]) AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library])
fi 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_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_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" 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} Session management: ${found_sm}
Shape extension: ${found_shape} Shape extension: ${found_shape}
Resize-and-rotate: ${found_randr} Resize-and-rotate: ${found_randr}
Xsync: ${found_xsync}
Deprecated config dialog: ${enable_config_dialog} Deprecated config dialog: ${enable_config_dialog}
" "

View File

@ -2,6 +2,7 @@
/* /*
* Copyright (C) 2001 Havoc Pennington * Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002 Red Hat, Inc.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * 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_ABOVE",
"_NET_WM_STATE_BELOW", "_NET_WM_STATE_BELOW",
"_NET_STARTUP_ID", "_NET_STARTUP_ID",
"_METACITY_TOGGLE_VERBOSE" "_METACITY_TOGGLE_VERBOSE",
"_METACITY_UPDATE_COUNTER",
"SYNC_COUNTER"
}; };
Atom atoms[G_N_ELEMENTS(atom_names)]; 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_wm_state_below = atoms[76];
display->atom_net_startup_id = atoms[77]; display->atom_net_startup_id = atoms[77];
display->atom_metacity_toggle_verbose = atoms[78]; display->atom_metacity_toggle_verbose = atoms[78];
display->atom_metacity_update_counter = atoms[79];
display->atom_sync_counter = atoms[80];
display->prop_hooks = NULL; display->prop_hooks = NULL;
meta_display_init_window_prop_hooks (display); meta_display_init_window_prop_hooks (display);
@ -453,6 +458,35 @@ meta_display_open (const char *name)
display->grab_screen = NULL; display->grab_screen = NULL;
display->grab_resize_popup = 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; screens = NULL;
#ifdef HAVE_GTK_MULTIHEAD #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. */ /* Get time of current event, or CurrentTime if none. */
guint32 guint32
meta_display_get_current_time (MetaDisplay *display) meta_display_get_current_time (MetaDisplay *display)
@ -1093,6 +1172,20 @@ event_callback (XEvent *event,
frame_was_receiver = TRUE; frame_was_receiver = TRUE;
meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event\n"); 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) switch (event->type)
{ {
@ -1242,25 +1335,22 @@ event_callback (XEvent *event,
} }
break; break;
case ButtonRelease: case ButtonRelease:
if (grab_op_is_mouse (display->grab_op) && if (display->grab_window == window &&
display->grab_window == window) grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
break; break;
case MotionNotify: case MotionNotify:
if (grab_op_is_mouse (display->grab_op) && if (display->grab_window == window &&
display->grab_window == window) grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
break; break;
case EnterNotify: case EnterNotify:
if (grab_op_is_mouse (display->grab_op) && if (display->grab_window == window &&
display->grab_window == window) grab_op_is_mouse (display->grab_op))
{ meta_window_handle_mouse_grab_op_event (window, event);
meta_window_handle_mouse_grab_op_event (window, event);
break;
}
/* do this even if window->has_focus to avoid races */ /* do this even if window->has_focus to avoid races */
if (window && !serial_is_ignored (display, event->xany.serial) && else if (window && !serial_is_ignored (display, event->xany.serial) &&
event->xcrossing.detail != NotifyInferior) event->xcrossing.detail != NotifyInferior)
{ {
switch (meta_prefs_get_focus_mode ()) switch (meta_prefs_get_focus_mode ())
{ {
@ -1317,13 +1407,10 @@ event_callback (XEvent *event,
} }
break; break;
case LeaveNotify: case LeaveNotify:
if (grab_op_is_mouse (display->grab_op) && if (display->grab_window == window &&
display->grab_window == window) grab_op_is_mouse (display->grab_op))
{ meta_window_handle_mouse_grab_op_event (window, event);
meta_window_handle_mouse_grab_op_event (window, event); else if (window != NULL)
break;
}
if (window)
{ {
switch (meta_prefs_get_focus_mode ()) switch (meta_prefs_get_focus_mode ())
{ {
@ -1872,6 +1959,7 @@ event_get_time (MetaDisplay *display,
} }
} }
#ifdef WITH_VERBOSE_MODE
const char* const char*
meta_event_detail_to_string (int d) meta_event_detail_to_string (int d)
{ {
@ -1908,7 +1996,9 @@ meta_event_detail_to_string (int d)
return detail; return detail;
} }
#endif /* WITH_VERBOSE_MODE */
#ifdef WITH_VERBOSE_MODE
const char* const char*
meta_event_mode_to_string (int m) meta_event_mode_to_string (int m)
{ {
@ -1936,7 +2026,9 @@ meta_event_mode_to_string (int m)
return mode; return mode;
} }
#endif /* WITH_VERBOSE_MODE */
#ifdef WITH_VERBOSE_MODE
static const char* static const char*
stack_mode_to_string (int mode) stack_mode_to_string (int mode)
{ {
@ -1956,7 +2048,9 @@ stack_mode_to_string (int mode)
return "Unknown"; return "Unknown";
} }
#endif /* WITH_VERBOSE_MODE */
#ifdef WITH_VERBOSE_MODE
static char* static char*
key_event_description (Display *xdisplay, key_event_description (Display *xdisplay,
XEvent *event) XEvent *event)
@ -1971,7 +2065,43 @@ key_event_description (Display *xdisplay,
return g_strdup_printf ("Key '%s' state 0x%x", return g_strdup_printf ("Key '%s' state 0x%x",
str ? str : "(null)", event->xkey.state); 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 static void
meta_spew_event (MetaDisplay *display, meta_spew_event (MetaDisplay *display,
XEvent *event) XEvent *event)
@ -2207,8 +2337,30 @@ meta_spew_event (MetaDisplay *display,
name = "MappingNotify"; name = "MappingNotify";
break; break;
default: default:
name = "(Unknown event)"; #ifdef HAVE_XSYNC
extra = g_strdup_printf ("type: %d", event->xany.type); 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; break;
} }
@ -2230,6 +2382,7 @@ meta_spew_event (MetaDisplay *display,
if (extra) if (extra)
g_free (extra); g_free (extra);
} }
#endif /* WITH_VERBOSE_MODE */
MetaWindow* MetaWindow*
meta_display_lookup_x_window (MetaDisplay *display, 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); cursor = xcursor_for_op (display, op);
#define GRAB_MASK (PointerMotionMask | PointerMotionHintMask | \ #define GRAB_MASK (PointerMotionMask | \
ButtonPressMask | ButtonReleaseMask | \ ButtonPressMask | ButtonReleaseMask | \
EnterWindowMask | LeaveWindowMask) EnterWindowMask | LeaveWindowMask)
if (change_pointer) if (change_pointer)
@ -2515,9 +2668,14 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_initial_root_y = root_y; display->grab_initial_root_y = root_y;
display->grab_current_root_x = root_x; display->grab_current_root_x = root_x;
display->grab_current_root_y = root_y; 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_sec = 0;
display->grab_last_moveresize_time.tv_usec = 0; display->grab_last_moveresize_time.tv_usec = 0;
#ifdef HAVE_XSYNC
display->grab_update_alarm = None;
#endif
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;
@ -2525,6 +2683,46 @@ meta_display_begin_grab_op (MetaDisplay *display,
&display->grab_initial_window_pos.x, &display->grab_initial_window_pos.x,
&display->grab_initial_window_pos.y); &display->grab_initial_window_pos.y);
display->grab_current_window_pos = display->grab_initial_window_pos; 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, meta_topic (META_DEBUG_WINDOW_OPS,
@ -2604,6 +2802,14 @@ meta_display_end_grab_op (MetaDisplay *display,
else else
meta_screen_ungrab_all_keys (display->grab_screen); 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_window = NULL;
display->grab_screen = NULL; display->grab_screen = NULL;

View File

@ -2,6 +2,7 @@
/* /*
* Copyright (C) 2001 Havoc Pennington * Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002 Red Hat, Inc.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@ -35,6 +36,10 @@
#include <libsn/sn.h> #include <libsn/sn.h>
#endif #endif
#ifdef HAVE_XSYNC
#include <X11/extensions/sync.h>
#endif
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0) #define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
/* this doesn't really belong here, oh well. */ /* this doesn't really belong here, oh well. */
@ -162,6 +167,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_sync_counter;
/* This is the actual window from focus events, /* This is the actual window from focus events,
* not the one we last set * not the one we last set
@ -229,6 +236,8 @@ struct _MetaDisplay
int grab_initial_root_y; int grab_initial_root_y;
int grab_current_root_x; int grab_current_root_x;
int grab_current_root_y; int grab_current_root_y;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask; gulong grab_mask;
guint grab_have_pointer : 1; guint grab_have_pointer : 1;
guint grab_have_keyboard : 1; guint grab_have_keyboard : 1;
@ -236,7 +245,10 @@ struct _MetaDisplay
MetaRectangle grab_current_window_pos; MetaRectangle grab_current_window_pos;
MetaResizePopup *grab_resize_popup; MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time; GTimeVal grab_last_moveresize_time;
#ifdef HAVE_XSYNC
/* alarm monitoring client's _METACITY_UPDATE_COUNTER */
XSyncAlarm grab_update_alarm;
#endif
/* Keybindings stuff */ /* Keybindings stuff */
MetaKeyBinding *screen_bindings; MetaKeyBinding *screen_bindings;
@ -275,11 +287,15 @@ struct _MetaDisplay
MetaGroupPropHooks *group_prop_hooks; MetaGroupPropHooks *group_prop_hooks;
#ifdef HAVE_STARTUP_NOTIFICATION #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; SnDisplay *sn_display;
#endif #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); 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); 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, gboolean meta_rectangle_intersect (MetaRectangle *src1,
MetaRectangle *src2, MetaRectangle *src2,
MetaRectangle *dest); MetaRectangle *dest);

View File

@ -280,6 +280,8 @@ topic_name (MetaDebugTopic topic)
return "PREFS"; return "PREFS";
case META_DEBUG_GROUPS: case META_DEBUG_GROUPS:
return "GROUPS"; return "GROUPS";
case META_DEBUG_RESIZING:
return "RESIZING";
} }
return "Window manager"; return "Window manager";

View File

@ -64,7 +64,8 @@ typedef enum
META_DEBUG_ERRORS = 1 << 14, META_DEBUG_ERRORS = 1 << 14,
META_DEBUG_STARTUP = 1 << 15, META_DEBUG_STARTUP = 1 << 15,
META_DEBUG_PREFS = 1 << 16, META_DEBUG_PREFS = 1 << 16,
META_DEBUG_GROUPS = 1 << 17 META_DEBUG_GROUPS = 1 << 17,
META_DEBUG_RESIZING = 1 << 18
} MetaDebugTopic; } MetaDebugTopic;

View File

@ -412,7 +412,32 @@ reload_net_startup_id (MetaWindow *window,
window->desc); 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 void
meta_display_init_window_prop_hooks (MetaDisplay *display) 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].init_func = init_net_startup_id;
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].init_func = init_update_counter;
hooks[i].reload_func = reload_update_counter;
++i;
if (i != N_HOOKS) if (i != N_HOOKS)
g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS); g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS);

View File

@ -159,7 +159,7 @@ meta_window_new (MetaDisplay *display,
GSList *tmp; GSList *tmp;
MetaWorkspace *space; MetaWorkspace *space;
gulong existing_wm_state; gulong existing_wm_state;
#define N_INITIAL_PROPS 9 #define N_INITIAL_PROPS 10
Atom initial_props[N_INITIAL_PROPS]; Atom initial_props[N_INITIAL_PROPS];
int i; int i;
@ -280,12 +280,16 @@ meta_window_new (MetaDisplay *display,
window->dialog_pipe = -1; window->dialog_pipe = -1;
window->xwindow = xwindow; window->xwindow = xwindow;
/* this is in window->screen->display, but that's too annoying to /* this is in window->screen->display, but that's too annoying to
* type * type
*/ */
window->display = display; window->display = display;
window->workspaces = NULL; window->workspaces = NULL;
#ifdef HAVE_XSYNC
window->update_counter = None;
#endif
window->screen = NULL; window->screen = NULL;
tmp = display->screens; 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_net_wm_desktop;
initial_props[i++] = display->atom_win_workspace; initial_props[i++] = display->atom_win_workspace;
initial_props[i++] = display->atom_net_startup_id; initial_props[i++] = display->atom_net_startup_id;
initial_props[i++] = display->atom_metacity_update_counter;
g_assert (N_INITIAL_PROPS == i); g_assert (N_INITIAL_PROPS == i);
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS); meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
@ -4138,6 +4143,13 @@ 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)
{
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; return TRUE;
} }
@ -6064,37 +6076,6 @@ 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 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 static void
clear_moveresize_time (MetaWindow *window) clear_moveresize_time (MetaWindow *window)
{ {
@ -6108,6 +6089,7 @@ check_moveresize_frequency (MetaWindow *window)
{ {
GTimeVal current_time; GTimeVal current_time;
double elapsed; double elapsed;
double max_resizes_per_second;
g_get_current_time (&current_time); 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 + ((((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; (current_time.tv_usec - window->display->grab_last_moveresize_time.tv_usec))) / 1000.0;
#define EPSILON (1e-6) #ifdef HAVE_XSYNC
#define MAX_RESIZES_PER_SECOND 20.0 if (window->display->grab_update_alarm != None)
if (elapsed >= 0.0 && elapsed < (1000.0 / MAX_RESIZES_PER_SECOND)) 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", meta_topic (META_DEBUG_RESIZING,
elapsed / 1000.0, 1.0 / MAX_RESIZES_PER_SECOND); "Delaying move/resize as only %g of %g seconds elapsed\n",
elapsed / 1000.0, 1.0 / max_resizes_per_second);
return FALSE; return FALSE;
} }
else if (elapsed < (0.0 - EPSILON)) /* handle clock getting set backward */ else if (elapsed < (0.0 - EPSILON)) /* handle clock getting set backward */
@ -6129,9 +6123,10 @@ check_moveresize_frequency (MetaWindow *window)
/* store latest time */ /* store latest time */
window->display->grab_last_moveresize_time = current_time; window->display->grab_last_moveresize_time = current_time;
meta_verbose ("Doing move/resize as %g of %g seconds elapsed\n", meta_topic (META_DEBUG_RESIZING,
elapsed / 1000.0, 1.0 / MAX_RESIZES_PER_SECOND); " Doing move/resize now (%g of %g seconds elapsed)\n",
elapsed / 1000.0, 1.0 / max_resizes_per_second);
return TRUE; return TRUE;
} }
@ -6144,6 +6139,10 @@ update_move (MetaWindow *window,
{ {
int dx, dy; int dx, dy;
int new_x, new_y; 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; dx = x - window->display->grab_current_root_x;
dy = y - window->display->grab_current_root_y; 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, /* 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 * 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) && if (!check_moveresize_frequency (window) &&
ABS (dx) < MOVE_THRESHOLD && ABS (dy) < MOVE_THRESHOLD) ABS (dx) < move_threshold && ABS (dy) < move_threshold)
return; return;
meta_window_move (window, TRUE, new_x, new_y); meta_window_move (window, TRUE, new_x, new_y);
@ -6176,6 +6180,11 @@ update_resize (MetaWindow *window,
int dx, dy; int dx, dy;
int new_w, new_h; int new_w, new_h;
int gravity; 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; dx = x - window->display->grab_current_root_x;
dy = y - window->display->grab_current_root_y; dy = y - window->display->grab_current_root_y;
@ -6232,108 +6241,140 @@ update_resize (MetaWindow *window,
/* Force a move regardless of time if a certain delta /* Force a move regardless of time if a certain delta
* is exceeded * 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) && if (!check_moveresize_frequency (window) &&
ABS (dx) < RESIZE_THRESHOLD && ABS (dy) < RESIZE_THRESHOLD) ABS (dx) < resize_threshold && ABS (dy) < resize_threshold)
return; return;
old = window->rect;
/* compute gravity of client during operation */ /* compute gravity of client during operation */
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op); gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
g_assert (gravity >= 0); g_assert (gravity >= 0);
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,
* 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 void
meta_window_handle_mouse_grab_op_event (MetaWindow *window, meta_window_handle_mouse_grab_op_event (MetaWindow *window,
XEvent *event) XEvent *event)
{ {
#ifdef HAVE_XSYNC
if (event->type == (window->display->xsync_event_base + XSyncAlarmNotify))
{
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_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:
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) switch (event->type)
{ {
case ButtonRelease: case ButtonRelease:
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:
clear_moveresize_time (window); 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);
break; }
else if (meta_grab_op_is_resizing (window->display->grab_op))
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:
clear_moveresize_time (window); 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);
break;
default:
break;
} }
meta_display_end_grab_op (window->display, event->xbutton.time); meta_display_end_grab_op (window->display, event->xbutton.time);
break; break;
case EnterNotify:
case LeaveNotify:
case MotionNotify: case MotionNotify:
switch (window->display->grab_op) if (meta_grab_op_is_moving (window->display->grab_op))
{ {
case META_GRAB_OP_MOVING: if (event->xmotion.root == window->screen->xroot)
case META_GRAB_OP_KEYBOARD_MOVING: update_move (window,
{ event->xmotion.state,
int x, y; event->xmotion.x_root,
if (window_query_root_pointer (window, &x, &y)) event->xmotion.y_root);
update_move (window, }
event->xbutton.state, else if (meta_grab_op_is_resizing (window->display->grab_op))
x, y); {
} if (event->xmotion.root == window->screen->xroot)
break; update_resize (window,
event->xmotion.x_root,
case META_GRAB_OP_RESIZING_E: event->xmotion.y_root);
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;
} }
break; break;
case EnterNotify:
case LeaveNotify:
if (meta_grab_op_is_moving (window->display->grab_op))
{
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: default:
break; break;
} }
@ -6711,9 +6752,7 @@ meta_window_update_resize_grab_op (MetaWindow *window,
window->display->grab_current_root_y = y + y_offset; window->display->grab_current_root_y = y + y_offset;
if (window->display->grab_window) if (window->display->grab_window)
{ window->display->grab_current_window_pos = window->rect;
window->display->grab_current_window_pos = window->rect;
}
if (update_cursor) if (update_cursor)
{ {

View File

@ -2,6 +2,7 @@
/* /*
* Copyright (C) 2001 Havoc Pennington * Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002 Red Hat, Inc.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@ -22,6 +23,7 @@
#ifndef META_WINDOW_H #ifndef META_WINDOW_H
#define META_WINDOW_H #define META_WINDOW_H
#include <config.h>
#include "screen.h" #include "screen.h"
#include "util.h" #include "util.h"
#include "stack.h" #include "stack.h"
@ -216,6 +218,11 @@ struct _MetaWindow
/* Info on which props we got our attributes from */ /* Info on which props we got our attributes from */
guint using_net_wm_name : 1; /* vs. plain wm_name */ guint using_net_wm_name : 1; /* vs. plain wm_name */
guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_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 /* Number of UnmapNotify that are caused by us, if
* we get UnmapNotify with none pending then the client * we get UnmapNotify with none pending then the client

View File

@ -505,6 +505,24 @@ window_from_results (GetPropertyResults *results,
return TRUE; 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 gboolean
meta_prop_get_window (MetaDisplay *display, meta_prop_get_window (MetaDisplay *display,
Window xwindow, Window xwindow,
@ -915,6 +933,9 @@ meta_prop_get_values (MetaDisplay *display,
case META_PROP_VALUE_SIZE_HINTS: case META_PROP_VALUE_SIZE_HINTS:
values[i].required_type = XA_WM_SIZE_HINTS; values[i].required_type = XA_WM_SIZE_HINTS;
break; 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].v.size_hints.flags))
values[i].type = META_PROP_VALUE_INVALID; values[i].type = META_PROP_VALUE_INVALID;
break; 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: next:
@ -1093,6 +1123,8 @@ free_value (MetaPropValue *value)
case META_PROP_VALUE_CARDINAL_LIST: case META_PROP_VALUE_CARDINAL_LIST:
meta_XFree (value->v.cardinal_list.cardinals); meta_XFree (value->v.cardinal_list.cardinals);
break; break;
case META_PROP_VALUE_SYNC_COUNTER:
break;
} }
} }

View File

@ -22,6 +22,7 @@
#ifndef META_XPROPS_H #ifndef META_XPROPS_H
#define META_XPROPS_H #define META_XPROPS_H
#include <config.h>
#include "display.h" #include "display.h"
#include <X11/Xutil.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_TEXT_PROPERTY, /* comes back as UTF-8 string */
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
} MetaPropValueType; } MetaPropValueType;
/* used to request/return/store property values */ /* used to request/return/store property values */
@ -160,6 +162,9 @@ typedef struct
gulong cardinal; gulong cardinal;
XWMHints *wm_hints; XWMHints *wm_hints;
XClassHint class_hint; XClassHint class_hint;
#ifdef HAVE_XSYNC
XSyncCounter xcounter;
#endif
struct struct
{ {