diff --git a/NEWS b/NEWS index 0f74d3856ae5660e7e017aba40345c843ec887e4..1d48e6bf358f2977cab4b258a39e5cd902438604 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 3.30.1 +============== +- Improve focus tracking + Version 3.30.0 ============== - Fix build warnings diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh index 436658703bbc911d061139423b70c7ab78880856..27c578911af072ea0fc0fc9db22ca02afdc6f107 100644 --- a/build-aux/ltmain.sh +++ b/build-aux/ltmain.sh @@ -31,7 +31,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.6 Debian-2.4.6-2.1build1" +VERSION="2.4.6 Debian-2.4.6-3.1" package_revision=2.4.6 @@ -2237,7 +2237,7 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname $scriptversion Debian-2.4.6-2.1build1 + version: $progname $scriptversion Debian-2.4.6-3.1 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` diff --git a/configure b/configure index 042386d62eee738bbefdb2de5e44d2db3d2d1f9e..4594a3328a0e63e1be59138828796065a8cf3068 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for metacity 3.30.0. +# Generated by GNU Autoconf 2.69 for metacity 3.30.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='metacity' PACKAGE_TARNAME='metacity' -PACKAGE_VERSION='3.30.0' -PACKAGE_STRING='metacity 3.30.0' +PACKAGE_VERSION='3.30.1' +PACKAGE_STRING='metacity 3.30.1' PACKAGE_BUGREPORT='https://bugzilla.gnome.org/enter_bug.cgi?product=metacity' PACKAGE_URL='' @@ -1414,7 +1414,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures metacity 3.30.0 to adapt to many kinds of systems. +\`configure' configures metacity 3.30.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1489,7 +1489,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of metacity 3.30.0:";; + short | recursive ) echo "Configuration of metacity 3.30.1:";; esac cat <<\_ACEOF @@ -1656,7 +1656,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -metacity configure 3.30.0 +metacity configure 3.30.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2208,7 +2208,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by metacity $as_me 3.30.0, which was +It was created by metacity $as_me 3.30.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -5796,7 +5796,7 @@ fi # Define the identity of the package. PACKAGE='metacity' - VERSION='3.30.0' + VERSION='3.30.1' cat >>confdefs.h <<_ACEOF @@ -16602,7 +16602,7 @@ $as_echo "#define METACITY_MAJOR_VERSION 3" >>confdefs.h $as_echo "#define METACITY_MINOR_VERSION 30" >>confdefs.h -$as_echo "#define METACITY_MICRO_VERSION 0" >>confdefs.h +$as_echo "#define METACITY_MICRO_VERSION 1" >>confdefs.h @@ -20572,7 +20572,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by metacity $as_me 3.30.0, which was +This file was extended by metacity $as_me 3.30.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20638,7 +20638,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -metacity config.status 3.30.0 +metacity config.status 3.30.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 6d76b1bdd5ce4a54eb388baccacf1e04e70e7899..27c4707d462616c711068772305184f16069a601 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ dnl ************************************************************************** m4_define([m_major_version], [3]) m4_define([m_minor_version], [30]) -m4_define([m_micro_version], [0]) +m4_define([m_micro_version], [1]) m4_define([m_version], [m_major_version.m_minor_version.m_micro_version]) dnl ************************************************************************** diff --git a/m4/libtool.m4 b/m4/libtool.m4 index ee80844b619f4e8689086457c4807c40fe238784..e67ed69978a1179f1d77e864e2d5bce2df0661b4 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -6438,7 +6438,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -6813,7 +6813,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6878,7 +6878,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -7217,7 +7217,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -7301,7 +7301,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7312,7 +7312,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' diff --git a/src/core/atomnames.h b/src/core/atomnames.h index 6e14219675bddcab1aa0b239e06e4fe54b17a99e..bab2630b8831dac1dfc248e046705dec28da5dab 100644 --- a/src/core/atomnames.h +++ b/src/core/atomnames.h @@ -62,6 +62,8 @@ item(_GTK_FRAME_EXTENTS) item(_GNOME_PANEL_ACTION) item(_GNOME_PANEL_ACTION_MAIN_MENU) item(_GNOME_PANEL_ACTION_RUN_DIALOG) +item(_METACITY_TIMESTAMP_PING) +item(_METACITY_FOCUS_SET) item(_METACITY_SENTINEL) item(_METACITY_VERSION) item(WM_CLIENT_MACHINE) diff --git a/src/core/display-private.h b/src/core/display-private.h index b7246ec92da4e4bb032de9bce8cf09b0bae605b3..8a2ee3ed415e70c15f71d78fb47503e799ff20df 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -127,6 +127,14 @@ struct _MetaDisplay */ guint allow_terminal_deactivation : 1; + /* If true, server->focus_serial refers to us changing the focus; in + * this case, we can ignore focus events that have exactly focus_serial, + * since we take care to make another request immediately afterwards. + * But if focus is being changed by another client, we have to accept + * multiple events with the same serial. + */ + guint focused_by_us : 1; + /*< private-ish >*/ guint error_trap_synced_at_last_pop : 1; MetaScreen *screen; diff --git a/src/core/display.c b/src/core/display.c index 7f0698e4c534f85a99628b230740e37b49e4bfa0..b048f5f4f1606588007b06a1f9bb5133559060a0 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1210,6 +1210,17 @@ meta_display_get_current_time (MetaDisplay *display) return display->current_time; } +static Bool +find_timestamp_predicate (Display *xdisplay, + XEvent *ev, + XPointer arg) +{ + MetaDisplay *display = (MetaDisplay *) arg; + + return (ev->type == PropertyNotify && + ev->xproperty.atom == display->atom__METACITY_TIMESTAMP_PING); +} + /* Get a timestamp, even if it means a roundtrip */ guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display) @@ -1221,17 +1232,13 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display) { XEvent property_event; - /* Using the property XA_PRIMARY because it's safe; nothing - * would use it as a property. The type doesn't matter. - */ - XChangeProperty (display->xdisplay, - display->timestamp_pinging_window, - XA_PRIMARY, XA_STRING, 8, - PropModeAppend, NULL, 0); - XWindowEvent (display->xdisplay, - display->timestamp_pinging_window, - PropertyChangeMask, - &property_event); + XChangeProperty (display->xdisplay, display->timestamp_pinging_window, + display->atom__METACITY_TIMESTAMP_PING, + XA_STRING, 8, PropModeAppend, NULL, 0); + XIfEvent (display->xdisplay, + &property_event, + find_timestamp_predicate, + (XPointer) display); timestamp = property_event.xproperty.time; } @@ -1408,9 +1415,11 @@ button_press_event_new (XEvent *xevent, static void update_focus_window (MetaDisplay *display, MetaWindow *window, - gulong serial) + gulong serial, + gboolean focused_by_us) { display->focus_serial = serial; + display->focused_by_us = focused_by_us; if (window == display->focus_window) return; @@ -1485,6 +1494,7 @@ request_xserver_input_focus_change (MetaDisplay *display, guint32 timestamp) { MetaWindow *meta_window; + gulong serial; if (timestamp_too_old (display, ×tamp)) return; @@ -1492,14 +1502,36 @@ request_xserver_input_focus_change (MetaDisplay *display, meta_window = meta_display_lookup_x_window (display, xwindow); meta_error_trap_push (display); - update_focus_window (display, - meta_window, - XNextRequest (display->xdisplay)); + + /* In order for mutter to know that the focus request succeeded, we track + * the serial of the "focus request" we made, but if we take the serial + * of the XSetInputFocus request, then there's no way to determine the + * difference between focus events as a result of the SetInputFocus and + * focus events that other clients send around the same time. Ensure that + * we know which is which by making two requests that the server will + * process at the same time. + */ + XGrabServer (display->xdisplay); + + serial = XNextRequest (display->xdisplay); XSetInputFocus (display->xdisplay, xwindow, RevertToPointerRoot, timestamp); + + XChangeProperty (display->xdisplay, display->timestamp_pinging_window, + display->atom__METACITY_FOCUS_SET, + XA_STRING, 8, PropModeAppend, NULL, 0); + + XUngrabServer (display->xdisplay); + XFlush (display->xdisplay); + + update_focus_window (display, + meta_window, + serial, + TRUE); + meta_error_trap_pop (display); display->last_focus_time = timestamp; @@ -1608,10 +1640,18 @@ handle_window_focus_event (MetaDisplay *display, else g_return_if_reached (); - if (display->server_focus_serial >= display->focus_serial) + /* If display->focused_by_us, then the focus_serial will be used only + * for a focus change we made and have already accounted for. + * (See request_xserver_input_focus_change().) Otherwise, we can get + * multiple focus events with the same serial. + */ + if (display->server_focus_serial > display->focus_serial || + (!display->focused_by_us && + display->server_focus_serial == display->focus_serial)) { update_focus_window (display, focus_window, - display->server_focus_serial); + display->server_focus_serial, + FALSE); } } @@ -1656,7 +1696,8 @@ event_callback (XEvent *event, display->current_time = event_get_time (display, event); display->monitor_cache_invalidated = TRUE; - if (event->xany.serial > display->focus_serial && + if (display->focused_by_us && + event->xany.serial > display->focus_serial && display->focus_window && display->focus_window->xwindow != display->server_focus_window) { @@ -1664,7 +1705,8 @@ event_callback (XEvent *event, display->focus_window->desc); update_focus_window (display, meta_display_lookup_x_window (display, display->server_focus_window), - display->server_focus_serial); + display->server_focus_serial, + FALSE); } modified = event_get_modified_window (display, event);