Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / workspace / kwin / README
bloba59e92b366a5870146352d52d5db41f995115451
1 - The mailing list for KWin is kwin@kde.org (https://mail.kde.org/mailman/listinfo/kwin).
3 - If you want to develop KWin, see file HACKING.
5 - If you want to check KWin's compliance with specifications, see file COMPLIANCE.
7 - File CONFIGURATION includes some details on configuring KWin.
9 - Below is some info for application developers about application interaction
10   with the window manager, but it'd need some cleanup.
19  This README is meant as an explanation of various window manager related
20 mechanisms that application developers need to be aware of. As some of these
21 concepts may be difficult to understand for people not having the required
22 background knowledge (since sometimes it's difficult even for people who
23 do have the knowledge), the mechanisms are first briefly explained, and
24 then an example of fixing the various problems is given.
26  For comments, questions, suggestions and whatever use the kwin@kde.org
27 mailing list.
30 Table of contents:
31 ==================
33 - Window relations
34     - how to make the window manager know which windows belong together
35 - Focus stealing prevention
36     - how to solve cases where focus stealing prevention doesn't work
37       properly automatically
41 Window relations:
42 =================
44 (For now, this explanation of window relations is mainly meant for
45 focus stealing prevention. To be extended later.)
47  All windows created by an application should be organized in a tree
48 with the root being the application's main window. Note that this is about
49 toplevel windows, not widgets inside the windows. For example, if you
50 have KWrite running, with a torn-off toolbar (i.e. a standalone toolbar),
51 a file save dialog open, and the file save dialog showing a dialog
52 for creating a directory, the window hiearchy should look like this:
55              KWrite mainwindow
56               /             \
57              /               \
58       file save dialog      torn-off toolbar
59             \
60              \
61           create directory dialog
63  Each subwindow (i.e. all except for the KWrite mainwindow) points to its
64 main window (which in turn may have another main window, as in the case
65 of the file save dialog). When the window manager knows these relations,
66 it can better arrange the windows (keeping subwindows above their
67 main windows, preventing activation of a main window of a modal dialog,
68 and similar). Failing to provide this information to the window manager
69 may have various results, for example having dialogs positioned below
70 the main window,
72 The window property used by subwindows to point to their mainwindows is
73 called WM_TRANSIENT_FOR. It can be seen by running
74 'xprop | grep WM_TRANSIENT_FOR' and clicking on a window. If the property
75 is not present, the window does not (claim to) have any mainwindow.
76 If the property is present, it's value is the window id of its main window;
77 window id of any window can be found out by running 'xwininfo'. A window
78 having WM_TRANSIENT_FOR poiting to another window is said to be transient
79 for that window.
81  In some cases, the WM_TRANSIENT_FOR property may not point to any other
82 existing window, having value of 0, or pointing to the screen number
83 ('xwininfo -root'). These special values mean that the window is transient
84 for all other windows in its window group. This should be used only
85 in rare cases, everytime a specific main window is known, WM_TRANSIENT_FOR
86 should be pointing to it instead of using one of these special values.
87 (The explanation why is beyond the scope of this document - just accept it
88 as a fact.)
90  With Qt, the WM_TRANSIENT_FOR property is set by Qt automatically, based
91 on the toplevel widget's parent. If the toplevel widget is of a normal
92 type (i.e. not a dialog, toolbar, etc.), Qt doesn't set WM_TRANSIENT_FOR
93 on it. For special widgets, such as dialogs, WM_TRANSIENT_FOR is set
94 to point to the widget's parent, if it has a specific parent, otherwise
95 WM_TRANSIENT_FOR points to the root window.
97  As already said above, WM_TRANSIENT_FOR poiting to the root window should
98 be usually avoided, so everytime the widget's main widget is known, the widget
99 should get it passed as a parent in its constructor.
100 (TODO KDialog etc. classes should not have a default argument for the parent
101 argument, and comments like 'just pass 0 as the parent' should go.)
105 Focus stealing prevention:
106 ==========================
108  Since KDE3.2 KWin has a feature called focus stealing prevention. As the name
109 suggests, it prevents unexpected changes of focus. With older versions of KWin,
110 if any application opened a new dialog, it became active, and
111 if the application's main window was on another virtual desktop, also
112 the virtual desktop was changed. This was annoying, and also sometimes led
113 to dialogs mistakenly being closed because they received keyboard input that
114 was meant for the previously active window.
116  The basic principle of focus stealing prevention is that the window with most
117 recent user activity wins. Any window of an application will become active
118 when being shown only if this application was the most recently used one.
119 KWin itself, and some of the related kdecore classes should take care
120 of the common cases, so usually there's no need for any special handling
121 in applications. Qt/KDE applications, that is. Applications using other
122 toolkits should in most cases work fine too. If they don't support
123 the window property _NET_WM_USER_TIME, the window manager may fail to detect
124 the user timestamp properly, resulting either in other windows becoming active
125 while the user works with this application, or this application may sometimes
126 steal focus (this second case should be very rare though).
128  There are also cases where KDE applications needs special handling. The two
129 most common cases are when windows relations are not setup properly to make
130 KWin realize that they belong to the same application, and when the user
131 activity is not represented by manipulating with the application windows
132 themselves.
134  Also note that focus stealing prevention implemented in the window manager
135 can only help with focus stealing between different applications.
136 If an application itself suddenly pops up a dialog, KWin cannot do anything about
137 it, and its the application's job to handle this case.
140 Window relations:
141 -----------------
143  The common case here is when a dialog is shown for an application, but this
144 dialog is not provided by the application itself, but by some other process.
145 For example, dialogs with warnings about accepted cookies are provided
146 by KCookieJar, instead of being shown by Konqueror. In the normal case,
147 from KWin's point of view the cookie dialog would be an attempt of another
148 application to show a dialog, and KWin wouldn't allow activation of this
149 window.
151  The solution is to tell the window manager about the relation between
152 the Konqueror main window and the cookie dialog, by making the dialog
153 point to the mainwindow. Note that this is not special to focus stealing
154 prevention, subwindows such as dialogs, toolbars and similar should always
155 point to their mainwindow. See the section on window relations for full
156 description.
158  The WM_TRANSIENT_FOR property that's set on dialogs to point to their
159 mainwindow should in the cookie dialog case point to the Konqueror window
160 for which it has been shown. This is solved in kcookiejar by including
161 the window id in the DCOP call. When the cookie dialog is shown, its
162 WM_TRANSIENT_FOR property is manually set using the XSetTransientForHint()
163 call (see kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp). The arguments
164 to XSetTransientForHint() call are the X display (i.e. QX11Info::display()),
165 the window id on which the WM_TRANSIENT_FOR property is to be set
166 (i.e. use QWidget::winId()), and the window id of the mainwindow.
169   Simple short HOWTO:
170   
171  To put it simply: Let's say you have a daemon application that has
172 DCOP call "showDialog( QString text )", and when this is called, it shows
173 a dialog with the given text. This won't work properly with focus stealing
174 prevention. The DCOP call should be changed to
175 "showDialog( QString text, long id )". The caller should pass something like
176 myMainWindow->winId() as the second argument. In the daemon, before
177 the dialog is shown, a call to XSetTransientHint() should be added:
179  XSetTransientForHint( QX11Info::display(), dialog->winId(), id_of_mainwindow );
181  That's it.
183 Non-standard user activity:
184 ---------------------------
186  The most common case in KDE will be DCOP calls. For example, KDesktop's DCOP
187 call "KDesktopIface popupExecuteCommand". Executing this DCOP call e.g.
188 from Konsole as 'dcop kdesktop KDesktopIface popupExecuteCommand" will lead
189 to showing the minicli, but the last user activity timestamp gained from events
190 sent by X server will be older than user activity timestamp of Konsole, and
191 would normally result in minicli not being active. Therefore, before showing
192 the minicli, kdesktop needs to call KApplication::updateUserTimestamp().
194  However, this shouldn't be done with all DCOP calls. If a DCOP call is not
195 a result of direct user action, calling KApplication::updateUserTimestamp()
196 would lead to focus stealing. For example, let's assume for a moment
197 that KMail would use this DCOP call in case it detects the modem is not
198 connected, allowing to you to start KPPP or whatever tool you use. If KMail
199 would be configured to check mail every 10 minutes, this would lead to minicli
200 possibly suddenly showing up at every check. Basically, doing the above change
201 to kdesktop's minicli means that the popupExecuteCommand() DCOP call is only
202 for user scripting. (TODO write about focus transferring?)
204  Simply said, KApplication::updateUserTimestamp() should be called only
205 as a result of user action. Unfortunately, I'm not aware of any universal
206 way how to handle this, so every case will have to be considered separately.