Focus stealing prevention



 Hello,

 ok, it took a litle longer. Attached are the additions to the spec that I 
find necesary for proper focus stealing prevention support (and also 
_NET_WM_USER_TIME, which is already there). Just for the record, this is the 
link when I posted some of these things previously: 
http://mail.gnome.org/archives/wm-spec-list/2003-May/msg00013.html . Also, 
http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdebase/kwin/activation.cpp should 
be basically all KWin's logic related to focus stealing prevention.

- demands_attention.patch - _NET_WM_STATE_DEMANDS_ATTENTION . I don't think 
this one needs comments, I stated here few days ago why I didn't use the 
urgency hint.

- user_time_fix.patch - small rewording for _NET_WM_USER_TIME . It now says 
that all key/button release events should not update the property, as it's 
possible they'll come after some action triggered by the matching press (e.g. 
you press, the app starts a new app, you release, the new app shows up, but 
the old one has newer timestamp)

- net_active.patch - new fields for the _NET_ACTIVE_WINDOW message that help 
deciding whether and how to obey the request. The source indication field is 
there before the WM can disobey the request if it feels like it, but it 
should always obey pagers etc. - it would feel stupid if clicking in a pager 
didn't do anything. Timestamp should be obvious.

 The currently active window is meant for cases like you have KAddressBook 
running, you start KMail, and KMail decides to activate KAddressBook. In this 
case, KAddressBook should be activated only if KMail currently is. I actually 
don't have yet any code for this.

- net_restack_window.patch - as a part of focus stealing prevention, KWin also 
doesn't allow raising inactive windows on top if they do XRaiseWindow() etc. 
In order to recongnize configure requests from pagers, a new message is 
needed, instead of plain ConfigureRequest.

- startup_notification.patch - this one is for completeness, for the startup 
notification spec, I think I haven't added it yet there

 One more thing that is needed is being able to recognize which windows belong 
together, see my recent 'extended WM_TRANSIENT_FOR mail'. I'm currently doing 
a bunch of guesses in KWin :-/, which seems to work quite good, but I'd like 
to get some consistent way how to do this. This window grouping is not 
strictly related to focus stealing prevention though, and we can discuss this 
separately (and I hope we will).

-- 
Lubos Lunak
KDE developer
---------------------------------------------------------------------
SuSE CR, s.r.o.  e-mail: l lunak suse cz , l lunak kde org
Drahobejlova 27  tel: +420 2 9654 2373
190 00 Praha 9   fax: +420 2 9654 2374
Czech Republic   http://www.suse.cz/
--- wm-spec.xml.sav	2003-09-30 17:07:35.000000000 +0200
+++ wm-spec.xml	2003-10-03 15:41:05.000000000 +0200
@@ -944,6 +944,7 @@ _NET_WM_STATE_HIDDEN, ATOM
 _NET_WM_STATE_FULLSCREEN, ATOM
 _NET_WM_STATE_ABOVE, ATOM
 _NET_WM_STATE_BELOW, ATOM
+_NET_WM_STATE_DEMANDS_ATTENTION, ATOM
 ]]></programlisting>
       <para>
 An implementation MAY add new atoms to this list. Implementations
@@ -1023,6 +1024,15 @@ windows (see <xref linkend="STACKINGORDE
        </para>
 
 	<para>
+_NET_WM_STATE_DEMANDS_ATTENTION indicates that some action in or with the window
+happened. For example, it may be set by the Window Manager if the window requested
+activation but the Window Manager refused it, or the application may set it if it
+finished some work. This state may be set by both the Client and
+the Window Manager. It should be unset by the Window Manager when it decides
+the window got the required attention (usually, that it got activated).
+	</para>
+
+	<para>
 To change the state of a mapped window, a Client MUST send a _NET_WM_STATE
 client message to the root window  (window is the respective window, type
 _NET_WM_STATE, format 32, l[0]=&lt;the action, as listed below&gt;,
--- wm-spec.xml.sav	2003-09-30 17:07:35.000000000 +0200
+++ wm-spec.xml	2003-10-03 15:32:05.000000000 +0200
@@ -1278,10 +1278,11 @@ window took place.
 Clients should keep the last timestamp from user interaction. and set
 this timestamp in this property on every new toplevel window before mapping it.
 A client that only deals with core events, might, for example, use the
-timestamp of the last KeyPress, ButtonPress, or ButtonRelease
-event. KeyRelease events should not generally be considered to
-be user interaction, because an application may receive KeyRelease
-events from global keybindings. Clients should start setting the property
+timestamp of the last KeyPress or ButtonPress event. ButtonRelease and KeyRelease
+events should not generally be considered to be user interaction, because an application
+may receive KeyRelease events from global keybindings, and generally release events
+may have later timestamp than actions that were triggered by the matching press events.
+Clients should start setting the property 
 only after receiving the first event from user interaction, they shouldn't set
 it before receiving first input event. The special value of zero on a newly
 mapped window means that the window shouldn't initially get focus after being mapped.
--- wm-spec.xml.sav	2003-10-06 18:29:19.000000000 +0200
+++ wm-spec.xml	2003-10-06 18:29:50.000000000 +0200
@@ -436,9 +436,26 @@ _NET_ACTIVE_WINDOW
   window  = window to activate
   message_type = _NET_ACTIVE_WINDOW
   format = 32
-  data.l[0] = 0 /* may be used later */
+  data.l[0] = source indication 
+  data.l[1] = timestamp
+  data.l[2] = requestor's currently active window, 0 if none
   other data.l[] elements = 0
 ]]></programlisting>
+        <para>
+Source indication should be 1 when the request comes from an application, and 2
+when it comes from a pager. Clients using older version of this spec use 0
+as source indication, see <xref linkend="sourceindication"/> for details.
+The timestamp is Client's last user activity timestamp (see _NET_WM_USER_TIME)
+at the time of the request, and the currently active window
+is the Client's active toplevel window, if any (the Window Manager may
+be e.g. more likely to obey the request if it will mean transferring
+focus from one active window to another).
+        </para>
+        <para>
+Depending on the information provided with the message, the Window Manager may
+decide to refuse the request (either completely ignore it, or e.g. use
+_NET_WM_STATE_DEMANDS_ATTENTION).
+        </para>
 	</sect2><sect2><title>_NET_WORKAREA</title>
 	<programlisting><![CDATA[
 _NET_WORKAREA, x, y, width, height CARDINAL[][4]/32
@@ -1751,6 +1768,22 @@ int net_get_hostname (char *buf, size_t 
 	focus.
       </para>
     </sect2>
+
+	<sect2 id="sourceindication">
+      <title>Source indication in requests</title>
+      <para>
+          Some requests from Clients include type of the Client, for example
+          the _NET_ACTIVE_WINDOW message. Currently the types can be
+          1 for normal applications, and 2 for pagers and other Clients
+          that represent direct user actions (the Window Manager may decide
+          to treat requests from applications differently than requests
+          that are result of direct user actions).
+          Clients that support only older version of this spec will have 0
+          as their source indication, thus not specifying their source at all.
+          This also may mean that some of the fields in the message comply
+          only with the older specification version.
+      </para>
+    </sect2>
 	</sect1>
   <sect1>
     <title>References</title>
--- wm-spec.xml.sav	2003-10-06 18:11:34.000000000 +0200
+++ wm-spec.xml	2003-10-06 18:14:10.000000000 +0200
@@ -760,6 +760,35 @@ _NET_WM_MOVERESIZE
 	terminate the operation, e.g. by pressing the ESC key.  
         </para>
 	</sect2>
+	<sect2><title>_NET_RESTACK_WINDOW</title>
+	<programlisting><![CDATA[
+_NET_RESTACK_WINDOW
+]]></programlisting>
+	<para>
+	Pagers wanting to restack a window SHOULD send a _NET_CLOSE_WINDOW client
+	message request to the root window:
+	</para>
+<programlisting><![CDATA[
+_NET_CLOSE_WINDOW
+  window = window to restack
+  message_type = _NET_CLOSE_WINDOW
+  format = 32
+  data.l[0] = source indication
+  data.l[1] = sibling window
+  data.l[2] = detail
+  other data.l[] elements = 0
+]]></programlisting>
+	<para>
+        This request is similar to ConfigureRequest with CWSibling and CWStackMode flags. It should be used only by pagers,
+        applications can use normal ConfigureRequests. The source indication field should be therefore set to 1,
+        see <xref linkend="sourceindication"/> for details.
+	</para>
+	<para>
+	Rationale: A Window Manager may put restrictions on configure requests from applications, for example it may
+        under some conditions refuse to raise a window. This request makes it clear it comes from a pager or similar
+        tool, and therefore the Window Manager should always obey it.
+	</para>
+	</sect2>
 	</sect1>	
 	<sect1>
 	<title>Application Window Properties</title>
--- startup-notification.txt.sav	2002-10-23 20:05:14.000000000 +0200
+++ startup-notification.txt	2003-05-15 14:50:11.000000000 +0200
@@ -234,6 +234,17 @@ The following keys may be provided optio
           This desktop is relative to the screen provided by 
           the SCREEN key.
 
+  TIMESTAMP
+
+          X server timestamp of the user action that caused this
+          launch. For example window manager that doesn't allow
+          stealing of focus by newly mapped windows while the user
+          works in an application can use this timestamp for windows
+          that have matching _NET_STARTUP_ID property if they don't
+          have any _NET_WM_USER_TIME property set or if it's older.
+          See the description of _NET_WM_USER_TIME in the WM spec
+          for details.
+
   DESCRIPTION   
 
           a short description suitable for display in a dialog that


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]