~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kwin/README

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

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