diff --git a/ChangeLog b/ChangeLog index 34f5e4b8c..0adff9716 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-01-09 Elijah Newren + + More thorough handling of source indication. Part of #326041. + + * src/window.c (window_activate): new function based off the old + meta_window_activate but which also takes source indication into + account, (meta_window_active): just call window_activate() with + the necessary source indication to get the behavior wanted, + (meta_window_client_message): check source indication too for + _net_active_window messages + + * src/window.h (enum MetaClientType): convenience enum for source + indication handling + 2006-01-09 Elijah Newren Make the taskbar less flash happy and fix up some related stacking diff --git a/src/window.c b/src/window.c index c1d1a9c20..f9fde8fd0 100644 --- a/src/window.c +++ b/src/window.c @@ -2354,19 +2354,28 @@ unminimize_window_and_all_transient_parents (MetaWindow *window) meta_window_foreach_ancestor (window, unminimize_func, NULL); } -void -meta_window_activate (MetaWindow *window, - guint32 timestamp) +static void +window_activate (MetaWindow *window, + guint32 timestamp, + MetaClientType source_indication) { + gboolean can_ignore_outdated_timestamps; meta_topic (META_DEBUG_FOCUS, - "_NET_ACTIVE_WINDOW message sent for %s at time %lu.\n", - window->desc, (unsigned long)timestamp); + "_NET_ACTIVE_WINDOW message sent for %s at time %lu " + "by client type %u.\n", + window->desc, (unsigned long)timestamp, source_indication); - /* Older EWMH spec didn't specify a timestamp, so it can be 0 and we - * have to treat that as a new request. + /* Older EWMH spec didn't specify a timestamp; we decide to honor these only + * if the app specifies that it is a pager. + * + * Update: Unconditionally honor 0 timestamps for now; we'll fight + * that battle later. Just remove the "FALSE &&" in order to only + * honor 0 timestamps for pagers. */ + can_ignore_outdated_timestamps = + (timestamp != 0 || (FALSE && source_indication != META_CLIENT_TYPE_PAGER)); if (XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time) && - timestamp != 0) + can_ignore_outdated_timestamps) { meta_topic (META_DEBUG_FOCUS, "last_user_time (%lu) is more recent; ignoring " @@ -2376,9 +2385,13 @@ meta_window_activate (MetaWindow *window, set_net_wm_state (window); return; } - - if (timestamp == 0) + + /* For those stupid pagers, get a valid timestamp and show a warning */ + if (timestamp == 0) { + meta_warning ("meta_window_activate called by a pager with a 0 timestamp; " + "the pager needs to be fixed.\n"); timestamp = meta_display_get_current_time_roundtrip (window->display); + } meta_window_set_user_time (window, timestamp); @@ -2403,6 +2416,21 @@ meta_window_activate (MetaWindow *window, meta_window_focus (window, timestamp); } +/* This function exists since most of the functionality in window_activate + * is useful for Metacity, but Metacity shouldn't need to specify a client + * type for itself. ;-) + */ +void +meta_window_activate (MetaWindow *window, + guint32 timestamp) +{ + /* We're not really a pager, but the behavior we want is the same as if + * we were such. If we change the pager behavior later, we could revisit + * this and just add extra flags to window_activate. + */ + window_activate (window, timestamp, META_CLIENT_TYPE_PAGER); +} + /* Manually fix all the weirdness explained in the big comment at the * beginning of meta_window_move_resize_internal() giving positions * expected by meta_window_constrain (i.e. positions & sizes of the @@ -4548,25 +4576,23 @@ meta_window_client_message (MetaWindow *window, else if (event->xclient.message_type == display->atom_net_active_window) { + MetaClientType source_indication; + guint32 timestamp; + meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n", window->desc); - if (event->xclient.data.l[0] != 0) - { - /* Client supports newer _NET_ACTIVE_WINDOW with a - * convenient timestamp - */ - meta_window_activate (window, - event->xclient.data.l[1]); - - } - else - { - /* Client using older EWMH _NET_ACTIVE_WINDOW without a - * timestamp - */ - meta_window_activate (window, meta_display_get_current_time (window->display)); - } + source_indication = event->xclient.data.l[0]; + timestamp = event->xclient.data.l[1]; + + if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED) + source_indication = META_CLIENT_TYPE_UNKNOWN; + + if (timestamp == 0) + /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */ + timestamp = meta_display_get_current_time (window->display); + + window_activate (window, timestamp, source_indication); return TRUE; } diff --git a/src/window.h b/src/window.h index b8d0cff0a..2f57919d7 100644 --- a/src/window.h +++ b/src/window.h @@ -58,6 +58,13 @@ typedef enum META_MAXIMIZE_VERTICAL = 1 << 1 } MetaMaximizeFlags; +typedef enum { + META_CLIENT_TYPE_UNKNOWN = 0, + META_CLIENT_TYPE_APPLICATION = 1, + META_CLIENT_TYPE_PAGER = 2, + META_CLIENT_TYPE_MAX_RECOGNIZED = 2 +} MetaClientType; + struct _MetaStruts { /* struts */