From: Dana Jansens Date: Sat, 17 Apr 2010 02:23:37 +0000 (-0400) Subject: event_curtime is replaced (publicly) by event_time() X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=197ee0ad4732c8668fe38a6b49e0a747866ef3ea;p=chaz%2Fopenbox event_curtime is replaced (publicly) by event_time() This function never returns CurrentTime, which is nice, cuz using CurrentTime for XSetFocus always sucks. If the current XEvent did not have a timestamp, then event_time() will find one. It finds the first timestamp available in the X event queue, meaning the earliest timestamp >= the current (nontimestamped) event. All future events should have a timestamp >= event_time(), so using this in XSetFocus() should not mess up any future calls we make to it. This change seems to work well, as it appears to fix bug #3648. --- diff --git a/openbox/client.c b/openbox/client.c index 3399b509..605a191f 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -209,9 +209,6 @@ void client_manage(Window window, ObPrompt *prompt) ob_debug("Managing window: 0x%lx", window); - /* we want to always have a valid time when the window is mapping */ - g_assert(event_curtime != CurrentTime); - /* choose the events we want to receive on the CLIENT window (ObPrompt windows can request events too) */ attrib_set.event_mask = CLIENT_EVENTMASK | @@ -273,7 +270,7 @@ void client_manage(Window window, ObPrompt *prompt) launch_time = sn_app_started(self->startup_id, self->class, self->name); if (!OBT_PROP_GET32(self->window, NET_WM_USER_TIME, CARDINAL, &user_time)) - user_time = event_curtime; + user_time = event_time(); /* do this after we have a frame.. it uses the frame to help determine the WM_STATE to apply. */ @@ -442,7 +439,7 @@ void client_manage(Window window, ObPrompt *prompt) ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s", activate ? "yes" : "no"); if (activate) { - activate = client_can_steal_focus(self, event_curtime, launch_time); + activate = client_can_steal_focus(self, event_time(), launch_time); if (!activate) { /* if the client isn't stealing focus, then hilite it so the user @@ -3400,7 +3397,7 @@ void client_close(ObClient *self) else { /* request the client to close with WM_DELETE_WINDOW */ OBT_PROP_MSG_TO(self->window, self->window, WM_PROTOCOLS, - OBT_PROP_ATOM(WM_DELETE_WINDOW), event_curtime, + OBT_PROP_ATOM(WM_DELETE_WINDOW), event_time(), 0, 0, 0, NoEventMask); /* we're trying to close the window, so see if it is responding. if it @@ -3854,7 +3851,7 @@ gboolean client_focus(ObClient *self) ob_debug_type(OB_DEBUG_FOCUS, "Focusing client \"%s\" (0x%x) at time %u", - self->title, self->window, event_curtime); + self->title, self->window, event_time()); /* if using focus_delay, stop the timer now so that focus doesn't go moving on us */ @@ -3866,7 +3863,7 @@ gboolean client_focus(ObClient *self) /* This can cause a BadMatch error with CurrentTime, or if an app passed in a bad time for _NET_WM_ACTIVE_WINDOW. */ XSetInputFocus(obt_display, self->window, RevertToPointerRoot, - event_curtime); + event_time()); } if (self->focus_notify) { @@ -3877,7 +3874,7 @@ gboolean client_focus(ObClient *self) ce.xclient.window = self->window; ce.xclient.format = 32; ce.xclient.data.l[0] = OBT_PROP_ATOM(WM_TAKE_FOCUS); - ce.xclient.data.l[1] = event_curtime; + ce.xclient.data.l[1] = event_time(); ce.xclient.data.l[2] = 0l; ce.xclient.data.l[3] = 0l; ce.xclient.data.l[4] = 0l; @@ -3925,7 +3922,7 @@ void client_activate(ObClient *self, gboolean desktop, if ((user && (desktop || self->desktop == DESKTOP_ALL || self->desktop == screen_desktop)) || - client_can_steal_focus(self, event_curtime, CurrentTime)) + client_can_steal_focus(self, event_time(), CurrentTime)) { client_present(self, here, raise, unshade); } diff --git a/openbox/event.c b/openbox/event.c index bcf887f6..02e9dcd3 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -97,10 +97,15 @@ static gboolean focus_delay_func(gpointer data); static gboolean unfocus_delay_func(gpointer data); static void focus_delay_client_dest(ObClient *client, gpointer data); -Time event_curtime = CurrentTime; -Time event_last_user_time = CurrentTime; -/*! The serial of the current X event */ +Time event_last_user_time; + +/*! The time of the current X event (if it had a timestamp) */ +static Time event_curtime; +/*! The source time that started the current X event (user-provided, so not + to be trusted) */ +static Time event_sourcetime; +/*! The serial of the current X event */ static gulong event_curserial; static gboolean focus_left_screen = FALSE; /*! A list of ObSerialRanges which are to be ignored for mouse enter events */ @@ -140,9 +145,9 @@ void event_startup(gboolean reconfig) client_add_destroy_notify(focus_delay_client_dest, NULL); - /* get an initial time for event_curtime (mapping the initial windows needs - a timestamp) */ - event_curtime = event_get_server_time(); + event_curtime = CurrentTime; + event_sourcetime = CurrentTime; + event_last_user_time = CurrentTime; } void event_shutdown(gboolean reconfig) @@ -211,7 +216,7 @@ static Window event_get_window(XEvent *e) return window; } -static inline Time event_time(const XEvent *e) +static inline Time event_get_timestamp(const XEvent *e) { Time t = CurrentTime; @@ -255,14 +260,7 @@ static inline Time event_time(const XEvent *e) static void event_set_curtime(XEvent *e) { - Time t = event_time(e); - - if (t == CurrentTime) { - /* Some events don't come with timestamps :( - ...but we want the time anyways. */ - if (e->type == MapRequest) - t = event_get_server_time(); - } + Time t = event_get_timestamp(e); /* watch that if we get an event earlier than the last specified user_time, which can happen if the clock goes backwards, we erase the last @@ -270,6 +268,7 @@ static void event_set_curtime(XEvent *e) if (t && event_last_user_time && event_time_after(event_last_user_time, t)) event_last_user_time = CurrentTime; + event_sourcetime = CurrentTime; event_curtime = t; } @@ -747,7 +746,7 @@ static void event_process(const XEvent *ec, gpointer data) /* if something happens and it's not from an XEvent, then we don't know the time */ - event_curtime = CurrentTime; + event_curtime = event_sourcetime = CurrentTime; event_curserial = 0; } @@ -768,11 +767,12 @@ static void event_handle_root(XEvent *e) if (msgtype == OBT_PROP_ATOM(NET_CURRENT_DESKTOP)) { guint d = e->xclient.data.l[0]; if (d < screen_num_desktops) { - event_curtime = e->xclient.data.l[1]; - if (event_curtime == 0) + if (e->xclient.data.l[1] == 0) ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_CURRENT_DESKTOP message is missing " "a timestamp"); + else + event_sourcetime = e->xclient.data.l[1]; screen_set_desktop(d, TRUE); } } else if (msgtype == OBT_PROP_ATOM(NET_NUMBER_OF_DESKTOPS)) { @@ -831,7 +831,7 @@ void event_enter_client(ObClient *client) data = g_slice_new(ObFocusDelayData); data->client = client; - data->time = event_curtime; + data->time = event_time(); data->serial = event_curserial; obt_main_loop_timeout_add(ob_main_loop, @@ -841,7 +841,7 @@ void event_enter_client(ObClient *client) } else { ObFocusDelayData data; data.client = client; - data.time = event_curtime; + data.time = event_time(); data.serial = event_curserial; focus_delay_func(&data); } @@ -866,7 +866,7 @@ void event_leave_client(ObClient *client) data = g_slice_new(ObFocusDelayData); data->client = client; - data->time = event_curtime; + data->time = event_time(); data->serial = event_curserial; obt_main_loop_timeout_add(ob_main_loop, @@ -876,7 +876,7 @@ void event_leave_client(ObClient *client) } else { ObFocusDelayData data; data.client = client; - data.time = event_curtime; + data.time = event_time(); data.serial = event_curserial; unfocus_delay_func(&data); } @@ -1423,13 +1423,11 @@ static void event_handle_client(ObClient *client, XEvent *e) so do not use this timestamp in event_curtime, as this would be used in XSetInputFocus. */ - /*event_curtime = e->xclient.data.l[1];*/ + event_sourcetime = e->xclient.data.l[1]; if (e->xclient.data.l[1] == 0) ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_ACTIVE_WINDOW message for window %s is" " missing a timestamp", client->title); - - event_curtime = event_get_server_time(); } else ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_ACTIVE_WINDOW message for window %s is " @@ -2080,7 +2078,7 @@ static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2) static gboolean focus_delay_func(gpointer data) { ObFocusDelayData *d = data; - Time old = event_curtime; + Time old = event_curtime; /* save the curtime */ event_curtime = d->time; event_curserial = d->serial; @@ -2093,7 +2091,7 @@ static gboolean focus_delay_func(gpointer data) static gboolean unfocus_delay_func(gpointer data) { ObFocusDelayData *d = data; - Time old = event_curtime; + Time old = event_curtime; /* save the curtime */ event_curtime = d->time; event_curserial = d->serial; @@ -2226,14 +2224,19 @@ gboolean event_time_after(guint32 t1, guint32 t2) Bool find_timestamp(Display *d, XEvent *e, XPointer a) { - const Time t = event_time(e); + const Time t = event_get_timestamp(e); return t != CurrentTime; } -Time event_get_server_time(void) +Time event_time(void) { XEvent event; + if (event_curtime) return event_curtime; + + /* Some events don't come with timestamps :( + ...but we can get one anyways >:) */ + /* Generate a timestamp so there is guaranteed at least one in the queue eventually */ XChangeProperty(obt_display, screen_support_win, @@ -2243,5 +2246,11 @@ Time event_get_server_time(void) /* Grab the first timestamp available */ XPeekIfEvent(obt_display, &event, find_timestamp, NULL); - return event.xproperty.time; + /* Save the time so we don't have to do this again for this event */ + return event_curtime = event.xproperty.time; +} + +Time event_source_time(void) +{ + return event_sourcetime; } diff --git a/openbox/event.h b/openbox/event.h index 4a8d7901..8a2a4cbc 100644 --- a/openbox/event.h +++ b/openbox/event.h @@ -28,8 +28,6 @@ struct _ObClient; to determine if the user is working in another window */ #define OB_EVENT_USER_TIME_DELAY (500) /* 0.5 seconds */ -/*! Time at which the last event with a timestamp occured. */ -extern Time event_curtime; /*! The last user-interaction time, as given by the clients */ extern Time event_last_user_time; @@ -66,6 +64,14 @@ void event_halt_focus_delay(void); comes at the same time or later than t2. */ gboolean event_time_after(guint32 t1, guint32 t2); -Time event_get_server_time(void); +/*! Time at which the current event occured. If this is not known, this + is a time at or after it, but at or before any other events we will process +*/ +Time event_time(void); +/*! A time at which an event happened that caused this current event to be + generated. This is a user-provided time and not to be trusted. + Returns CurrentTime if there was no source time provided. + */ +Time event_source_time(void); #endif diff --git a/openbox/focus.c b/openbox/focus.c index d86f1c0b..8c023618 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -194,7 +194,7 @@ void focus_nothing(void) /* when nothing will be focused, send focus to the backup target */ XSetInputFocus(obt_display, screen_support_win, RevertToPointerRoot, - event_curtime); + event_time()); } void focus_order_add_new(ObClient *c) diff --git a/openbox/grab.c b/openbox/grab.c index f82592f3..4518c433 100644 --- a/openbox/grab.c +++ b/openbox/grab.c @@ -44,7 +44,7 @@ static ObtIC *ic = NULL; static Time ungrab_time(void) { - Time t = event_curtime; + Time t = event_time(); if (grab_time == CurrentTime || !(t == CurrentTime || event_time_after(t, grab_time))) /* When the time moves backward on the server, then we can't use @@ -87,12 +87,12 @@ gboolean grab_keyboard_full(gboolean grab) if (kgrabs++ == 0) { ret = XGrabKeyboard(obt_display, grab_window(), False, GrabModeAsync, GrabModeAsync, - event_curtime) == Success; + event_time()) == Success; if (!ret) --kgrabs; else { passive_count = 0; - grab_time = event_curtime; + grab_time = event_time(); } } else ret = TRUE; @@ -117,11 +117,11 @@ gboolean grab_pointer_full(gboolean grab, gboolean owner_events, GRAB_PTR_MASK, GrabModeAsync, GrabModeAsync, (confine ? obt_root(ob_screen) : None), - ob_cursor(cur), event_curtime) == Success; + ob_cursor(cur), event_time()) == Success; if (!ret) --pgrabs; else - grab_time = event_curtime; + grab_time = event_time(); } else ret = TRUE; } else if (pgrabs > 0) { @@ -238,7 +238,7 @@ void ungrab_passive_key(void) /*ob_debug("ungrabbing %d passive grabs\n", passive_count);*/ if (passive_count) { /* kill our passive grab */ - XUngrabKeyboard(obt_display, event_curtime); + XUngrabKeyboard(obt_display, event_time()); passive_count = 0; } } diff --git a/openbox/mouse.c b/openbox/mouse.c index a7601f69..2f8604eb 100644 --- a/openbox/mouse.c +++ b/openbox/mouse.c @@ -200,7 +200,7 @@ void mouse_replay_pointer(void) { if (replay_pointer_needed) { /* replay the pointer event before any windows move */ - XAllowEvents(obt_display, ReplayPointer, event_curtime); + XAllowEvents(obt_display, ReplayPointer, event_time()); replay_pointer_needed = FALSE; } } diff --git a/openbox/moveresize.c b/openbox/moveresize.c index aa1957af..cb0d2101 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -388,7 +388,7 @@ static void do_resize(void) ce.xclient.window = moveresize_client->window; ce.xclient.format = 32; ce.xclient.data.l[0] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST); - ce.xclient.data.l[1] = event_curtime; + ce.xclient.data.l[1] = event_time(); ce.xclient.data.l[2] = XSyncValueLow32(val); ce.xclient.data.l[3] = XSyncValueHigh32(val); ce.xclient.data.l[4] = 0l; diff --git a/openbox/prompt.c b/openbox/prompt.c index 50d09037..77398c5f 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -462,7 +462,7 @@ void prompt_show(ObPrompt *self, ObClient *parent, gboolean modal) /* activate the prompt */ OBT_PROP_MSG(ob_screen, self->super.window, NET_ACTIVE_WINDOW, 1, /* from an application.. */ - event_curtime, + event_time(), 0, 0, 0); return; diff --git a/openbox/screen.c b/openbox/screen.c index e939b01d..2ff950ab 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -116,7 +116,7 @@ static gboolean replace_wm(void) current_wm_sn_owner = None; } - timestamp = event_get_server_time(); + timestamp = event_time(); XSetSelectionOwner(obt_display, wm_sn_atom, screen_support_win, timestamp); @@ -731,8 +731,8 @@ void screen_set_desktop(guint num, gboolean dofocus) event_end_ignore_all_enters(ignore_start); - if (event_curtime != CurrentTime) - screen_desktop_user_time = event_curtime; + if (event_source_time() != CurrentTime) + screen_desktop_user_time = event_source_time(); } void screen_add_desktop(gboolean current) diff --git a/openbox/startupnotify.c b/openbox/startupnotify.c index aa6db7e6..c300d57d 100644 --- a/openbox/startupnotify.c +++ b/openbox/startupnotify.c @@ -255,7 +255,7 @@ void sn_setup_spawn_environment(const gchar *program, const gchar *name, if (desktop >= 0 && (unsigned) desktop < screen_num_desktops) sn_launcher_context_set_workspace(sn_launcher, (signed) desktop); sn_launcher_context_initiate(sn_launcher, "openbox", program, - event_curtime); + event_time()); id = sn_launcher_context_get_startup_id(sn_launcher); /* 20 second timeout for apps to start */