1 |
commit: efda8b45cbcf960f15659fecd823a2c2ed7e316a |
2 |
Author: Andreas Sturmlechner <andreas.sturmlechner <AT> gmail <DOT> com> |
3 |
AuthorDate: Sun Jun 26 19:30:51 2016 +0000 |
4 |
Commit: Michael Palimaka <kensington <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Jun 26 20:36:30 2016 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=efda8b45 |
7 |
|
8 |
kde-plasma/plasma-workspace: Add back legacy (gtk2) session mgmt |
9 |
|
10 |
Upstream dropped it in 5.6 but later found out it was still in use by |
11 |
Mozilla applications et al., thus reverted in Plasma/5.6 branch but |
12 |
only after 5.6.5.1 release. |
13 |
|
14 |
See also: https://bugs.kde.org/show_bug.cgi?id=362671 |
15 |
|
16 |
Package-Manager: portage-2.2.28 |
17 |
|
18 |
...sma-workspace-5.6.5.1-legacy-session-mgmt.patch | 558 +++++++++++++++++++++ |
19 |
.../plasma-workspace-5.6.5.1-r2.ebuild | 168 +++++++ |
20 |
2 files changed, 726 insertions(+) |
21 |
|
22 |
diff --git a/kde-plasma/plasma-workspace/files/plasma-workspace-5.6.5.1-legacy-session-mgmt.patch b/kde-plasma/plasma-workspace/files/plasma-workspace-5.6.5.1-legacy-session-mgmt.patch |
23 |
new file mode 100644 |
24 |
index 0000000..94cc1df |
25 |
--- /dev/null |
26 |
+++ b/kde-plasma/plasma-workspace/files/plasma-workspace-5.6.5.1-legacy-session-mgmt.patch |
27 |
@@ -0,0 +1,558 @@ |
28 |
+commit e4a76cd947759fd723935965ca30c00021601a45 |
29 |
+Author: Andreas Hartmetz <ahartmetz@×××××.com> |
30 |
+Date: Thu Jun 23 19:36:18 2016 +0200 |
31 |
+ |
32 |
+ Revert "Remove legacy session management support." |
33 |
+ |
34 |
+ This reverts commit 5f0ca1305db4a925dbdbf927f541497be334feff. |
35 |
+ |
36 |
+ Firefox and some GTK+ 2 applications still seem to use the old way. |
37 |
+ For shame. |
38 |
+ |
39 |
+ BUG: 362671 |
40 |
+ |
41 |
+--- a/ksmserver/CMakeLists.txt |
42 |
++++ b/ksmserver/CMakeLists.txt |
43 |
+@@ -15,4 +15,5 @@ set(ksmserver_KDEINIT_SRCS |
44 |
+ shutdowndlg.cpp |
45 |
+ switchuserdialog.cpp |
46 |
++ legacy.cpp |
47 |
+ startup.cpp |
48 |
+ shutdown.cpp |
49 |
+--- /dev/null |
50 |
++++ b/ksmserver/legacy.cpp |
51 |
+@@ -0,0 +1,419 @@ |
52 |
++/***************************************************************** |
53 |
++ksmserver - the KDE session management server |
54 |
++ |
55 |
++Copyright 2000 Matthias Ettrich <ettrich@×××.org> |
56 |
++Copyright 2005 Lubos Lunak <l.lunak@×××.org> |
57 |
++ |
58 |
++relatively small extensions by Oswald Buddenhagen <ob6@××××××××××××××.de> |
59 |
++ |
60 |
++some code taken from the dcopserver (part of the KDE libraries), which is |
61 |
++Copyright 1999 Matthias Ettrich <ettrich@×××.org> |
62 |
++Copyright 1999 Preston Brown <pbrown@×××.org> |
63 |
++ |
64 |
++Permission is hereby granted, free of charge, to any person obtaining a copy |
65 |
++of this software and associated documentation files (the "Software"), to deal |
66 |
++in the Software without restriction, including without limitation the rights |
67 |
++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
68 |
++copies of the Software, and to permit persons to whom the Software is |
69 |
++furnished to do so, subject to the following conditions: |
70 |
++ |
71 |
++The above copyright notice and this permission notice shall be included in |
72 |
++all copies or substantial portions of the Software. |
73 |
++ |
74 |
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
75 |
++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
76 |
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
77 |
++AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
78 |
++AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
79 |
++CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
80 |
++ |
81 |
++******************************************************************/ |
82 |
++ |
83 |
++#include <QtX11Extras/QX11Info> |
84 |
++#include <QDebug> |
85 |
++ |
86 |
++#include <config-workspace.h> |
87 |
++ |
88 |
++#include <ksmserver_debug.h> |
89 |
++ |
90 |
++#ifdef HAVE_SYS_TIME_H |
91 |
++#include <sys/time.h> |
92 |
++#endif |
93 |
++ |
94 |
++#include "server.h" |
95 |
++ |
96 |
++#include <unistd.h> |
97 |
++ |
98 |
++ |
99 |
++#include <kconfig.h> |
100 |
++#include <kconfiggroup.h> |
101 |
++#include <KSharedConfig> |
102 |
++#include <kshell.h> |
103 |
++#include <kwindowsystem.h> |
104 |
++ |
105 |
++#include <X11/Xlib.h> |
106 |
++#include <X11/Xutil.h> |
107 |
++#include <X11/Xatom.h> |
108 |
++ |
109 |
++/* |
110 |
++* Legacy session management |
111 |
++*/ |
112 |
++ |
113 |
++#ifndef NO_LEGACY_SESSION_MANAGEMENT |
114 |
++static WindowMap* windowMapPtr = 0; |
115 |
++ |
116 |
++static Atom wm_save_yourself = XNone; |
117 |
++static Atom wm_protocols = XNone; |
118 |
++static Atom wm_client_leader = XNone; |
119 |
++static Atom sm_client_id = XNone; |
120 |
++ |
121 |
++static int winsErrorHandler(Display *, XErrorEvent *ev) |
122 |
++{ |
123 |
++ if (windowMapPtr) { |
124 |
++ WindowMap::Iterator it = windowMapPtr->find(ev->resourceid); |
125 |
++ if (it != windowMapPtr->end()) |
126 |
++ (*it).type = SM_ERROR; |
127 |
++ } |
128 |
++ return 0; |
129 |
++} |
130 |
++ |
131 |
++void KSMServer::performLegacySessionSave() |
132 |
++{ |
133 |
++ qCDebug(KSMSERVER) << "Saving legacy session apps"; |
134 |
++ if (state == ClosingSubSession) |
135 |
++ return; //FIXME implement later |
136 |
++ |
137 |
++ KSharedConfig::Ptr config = KSharedConfig::openConfig(); |
138 |
++ config->reparseConfiguration(); // config may have changed in the KControl module |
139 |
++ KConfigGroup cg( config, "General" ); |
140 |
++ |
141 |
++ int wmSaveYourselfTimeout = cg.readEntry( "legacySaveTimeoutSecs", 4 ) * 1000; |
142 |
++ |
143 |
++ // Setup error handler |
144 |
++ legacyWindows.clear(); |
145 |
++ windowMapPtr = &legacyWindows; |
146 |
++ XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler); |
147 |
++ // Compute set of leader windows that need legacy session management |
148 |
++ // and determine which style (WM_COMMAND or WM_SAVE_YOURSELF) |
149 |
++ if( wm_save_yourself == (Atom)XNone ) { |
150 |
++ Atom atoms[ 4 ]; |
151 |
++ const char* const names[] |
152 |
++ = { "WM_SAVE_YOURSELF", "WM_PROTOCOLS", "WM_CLIENT_LEADER", "SM_CLIENT_ID" }; |
153 |
++ XInternAtoms( QX11Info::display(), const_cast< char** >( names ), 4, |
154 |
++ False, atoms ); |
155 |
++ wm_save_yourself = atoms[ 0 ]; |
156 |
++ wm_protocols = atoms[ 1 ]; |
157 |
++ wm_client_leader = atoms[ 2 ]; |
158 |
++ sm_client_id = atoms[ 3 ]; |
159 |
++ } |
160 |
++ const QList<WId> windows = KWindowSystem::windows(); |
161 |
++ for ( QList<WId>::ConstIterator it = windows.begin(); |
162 |
++ it != windows.end(); ++it) { |
163 |
++ WId leader = windowWmClientLeader( *it ); |
164 |
++ if (!legacyWindows.contains(leader) && windowSessionId( *it, leader ).isEmpty()) { |
165 |
++ SMType wtype = SM_WMCOMMAND; |
166 |
++ int nprotocols = 0; |
167 |
++ Atom *protocols = 0; |
168 |
++ if( XGetWMProtocols(QX11Info::display(), leader, &protocols, &nprotocols)) { |
169 |
++ for (int i=0; i<nprotocols; i++) |
170 |
++ if (protocols[i] == wm_save_yourself) { |
171 |
++ wtype = SM_WMSAVEYOURSELF; |
172 |
++ break; |
173 |
++ } |
174 |
++ XFree((void*) protocols); |
175 |
++ } |
176 |
++ SMData data; |
177 |
++ data.type = wtype; |
178 |
++ XClassHint classHint; |
179 |
++ if( XGetClassHint( QX11Info::display(), leader, &classHint ) ) { |
180 |
++ data.wmclass1 = QString::fromLocal8Bit( classHint.res_name ); |
181 |
++ data.wmclass2 = QString::fromLocal8Bit( classHint.res_class ); |
182 |
++ XFree( classHint.res_name ); |
183 |
++ XFree( classHint.res_class ); |
184 |
++ } |
185 |
++ legacyWindows.insert(leader, data); |
186 |
++ } |
187 |
++ } |
188 |
++ // Open fresh display for sending WM_SAVE_YOURSELF |
189 |
++ XSync(QX11Info::display(), False); |
190 |
++ Display *newdisplay = XOpenDisplay(DisplayString(QX11Info::display())); |
191 |
++ if (!newdisplay) { |
192 |
++ windowMapPtr = NULL; |
193 |
++ XSetErrorHandler(oldHandler); |
194 |
++ return; |
195 |
++ } |
196 |
++ WId root = DefaultRootWindow(newdisplay); |
197 |
++ XGrabKeyboard(newdisplay, root, False, |
198 |
++ GrabModeAsync, GrabModeAsync, CurrentTime); |
199 |
++ XGrabPointer(newdisplay, root, False, Button1Mask|Button2Mask|Button3Mask, |
200 |
++ GrabModeAsync, GrabModeAsync, XNone, XNone, CurrentTime); |
201 |
++ // Send WM_SAVE_YOURSELF messages |
202 |
++ XEvent ev; |
203 |
++ int awaiting_replies = 0; |
204 |
++ for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { |
205 |
++ if ( (*it).type == SM_WMSAVEYOURSELF ) { |
206 |
++ WId w = it.key(); |
207 |
++ awaiting_replies += 1; |
208 |
++ memset(&ev, 0, sizeof(ev)); |
209 |
++ ev.xclient.type = ClientMessage; |
210 |
++ ev.xclient.window = w; |
211 |
++ ev.xclient.message_type = wm_protocols; |
212 |
++ ev.xclient.format = 32; |
213 |
++ ev.xclient.data.l[0] = wm_save_yourself; |
214 |
++ ev.xclient.data.l[1] = QX11Info::appTime(); |
215 |
++ XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask); |
216 |
++ XSendEvent(newdisplay, w, False, 0, &ev); |
217 |
++ qCDebug(KSMSERVER) << "sent >save yourself< to legacy app " << (*it).wmclass1 << (*it).wmclass2; |
218 |
++ } |
219 |
++ } |
220 |
++ // Wait for change in WM_COMMAND with timeout |
221 |
++ XFlush(newdisplay); |
222 |
++ QTime start = QTime::currentTime(); |
223 |
++ while (awaiting_replies > 0) { |
224 |
++ if (XPending(newdisplay)) { |
225 |
++ /* Process pending event */ |
226 |
++ XNextEvent(newdisplay, &ev); |
227 |
++ if ( ( ev.xany.type == UnmapNotify ) || |
228 |
++ ( ev.xany.type == PropertyNotify && ev.xproperty.atom == XA_WM_COMMAND ) ) { |
229 |
++ WindowMap::Iterator it = legacyWindows.find( ev.xany.window ); |
230 |
++ if ( it != legacyWindows.end() && (*it).type != SM_WMCOMMAND ) { |
231 |
++ awaiting_replies -= 1; |
232 |
++ if ( (*it).type != SM_ERROR ) |
233 |
++ (*it).type = SM_WMCOMMAND; |
234 |
++ } |
235 |
++ } |
236 |
++ } else { |
237 |
++ /* Check timeout */ |
238 |
++ int msecs = start.elapsed(); |
239 |
++ if (msecs >= wmSaveYourselfTimeout) { |
240 |
++ qCDebug(KSMSERVER) << "legacy timeout expired"; |
241 |
++ break; |
242 |
++ } |
243 |
++ /* Wait for more events */ |
244 |
++ fd_set fds; |
245 |
++ FD_ZERO(&fds); |
246 |
++ int fd = ConnectionNumber(newdisplay); |
247 |
++ FD_SET(fd, &fds); |
248 |
++ struct timeval tmwait; |
249 |
++ tmwait.tv_sec = (wmSaveYourselfTimeout - msecs) / 1000; |
250 |
++ tmwait.tv_usec = ((wmSaveYourselfTimeout - msecs) % 1000) * 1000; |
251 |
++ ::select(fd+1, &fds, NULL, &fds, &tmwait); |
252 |
++ } |
253 |
++ } |
254 |
++ // Terminate work in new display |
255 |
++ XAllowEvents(newdisplay, ReplayPointer, CurrentTime); |
256 |
++ XAllowEvents(newdisplay, ReplayKeyboard, CurrentTime); |
257 |
++ XSync(newdisplay, False); |
258 |
++ XCloseDisplay(newdisplay); |
259 |
++ // Restore old error handler |
260 |
++ XSync(QX11Info::display(), False); |
261 |
++ XSetErrorHandler(oldHandler); |
262 |
++ for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { |
263 |
++ if ( (*it).type != SM_ERROR) { |
264 |
++ WId w = it.key(); |
265 |
++ (*it).wmCommand = windowWmCommand(w); |
266 |
++ (*it).wmClientMachine = windowWmClientMachine(w); |
267 |
++ } |
268 |
++ } |
269 |
++ qCDebug(KSMSERVER) << "Done saving " << legacyWindows.count() << " legacy session apps"; |
270 |
++} |
271 |
++ |
272 |
++/*! |
273 |
++Stores legacy session management data |
274 |
++*/ |
275 |
++void KSMServer::storeLegacySession( KConfig* config ) |
276 |
++{ |
277 |
++ if (state == ClosingSubSession) |
278 |
++ return; //FIXME implement later |
279 |
++ // Write LegacySession data |
280 |
++ config->deleteGroup( QStringLiteral( "Legacy" ) + sessionGroup ); |
281 |
++ KConfigGroup group( config, QStringLiteral( "Legacy" ) + sessionGroup ); |
282 |
++ int count = 0; |
283 |
++ for (WindowMap::ConstIterator it = legacyWindows.constBegin(); it != legacyWindows.constEnd(); ++it) { |
284 |
++ if ( (*it).type != SM_ERROR) { |
285 |
++ if( excludeApps.contains( (*it).wmclass1.toLower()) |
286 |
++ || excludeApps.contains( (*it).wmclass2.toLower())) |
287 |
++ continue; |
288 |
++ if ( !(*it).wmCommand.isEmpty() && !(*it).wmClientMachine.isEmpty() ) { |
289 |
++ count++; |
290 |
++ QString n = QString::number(count); |
291 |
++ group.writeEntry( QStringLiteral("command")+n, (*it).wmCommand ); |
292 |
++ group.writeEntry( QStringLiteral("clientMachine")+n, (*it).wmClientMachine ); |
293 |
++ } |
294 |
++ } |
295 |
++ } |
296 |
++ group.writeEntry( "count", count ); |
297 |
++} |
298 |
++ |
299 |
++/*! |
300 |
++Restores legacy session management data (i.e. restart applications) |
301 |
++*/ |
302 |
++void KSMServer::restoreLegacySession( KConfig* config ) |
303 |
++{ |
304 |
++ if( config->hasGroup( QStringLiteral( "Legacy" ) + sessionGroup )) { |
305 |
++ KConfigGroup group( config, QStringLiteral( "Legacy" ) + sessionGroup ); |
306 |
++ restoreLegacySessionInternal( &group ); |
307 |
++ } else if( wm == QStringLiteral( "kwin" ) ) { // backwards comp. - get it from kwinrc |
308 |
++ KConfigGroup group( config, sessionGroup ); |
309 |
++ int count = group.readEntry( "count", 0 ); |
310 |
++ for ( int i = 1; i <= count; i++ ) { |
311 |
++ QString n = QString::number(i); |
312 |
++ if ( group.readEntry( QStringLiteral("program")+n, QString() ) != wm ) |
313 |
++ continue; |
314 |
++ QStringList restartCommand = |
315 |
++ group.readEntry( QStringLiteral("restartCommand")+n, QStringList() ); |
316 |
++ for( QStringList::ConstIterator it = restartCommand.constBegin(); |
317 |
++ it != restartCommand.constEnd(); |
318 |
++ ++it ) { |
319 |
++ if( (*it) == QStringLiteral( "-session" ) ) { |
320 |
++ ++it; |
321 |
++ if( it != restartCommand.constEnd()) { |
322 |
++ KConfig cfg( QStringLiteral( "session/" ) + wm + |
323 |
++ QLatin1Char( '_' ) + (*it) ); |
324 |
++ KConfigGroup group(&cfg, "LegacySession"); |
325 |
++ restoreLegacySessionInternal( &group, ' ' ); |
326 |
++ } |
327 |
++ } |
328 |
++ } |
329 |
++ } |
330 |
++ } |
331 |
++} |
332 |
++ |
333 |
++void KSMServer::restoreLegacySessionInternal( KConfigGroup* config, char sep ) |
334 |
++{ |
335 |
++ int count = config->readEntry( "count",0 ); |
336 |
++ for ( int i = 1; i <= count; i++ ) { |
337 |
++ QString n = QString::number(i); |
338 |
++ QStringList wmCommand = (sep == ',') ? |
339 |
++ config->readEntry( QStringLiteral("command")+n, QStringList() ) : |
340 |
++ KShell::splitArgs( config->readEntry( QStringLiteral("command")+n, QString() ) ); // close enough(?) |
341 |
++ if( wmCommand.isEmpty()) |
342 |
++ continue; |
343 |
++ if( isWM( wmCommand.first())) |
344 |
++ continue; |
345 |
++ startApplication( wmCommand, |
346 |
++ config->readEntry( QStringLiteral("clientMachine")+n, QString() ), |
347 |
++ config->readEntry( QStringLiteral("userId")+n, QString() )); |
348 |
++ } |
349 |
++} |
350 |
++ |
351 |
++static QByteArray getQCStringProperty(WId w, Atom prop) |
352 |
++{ |
353 |
++ Atom type; |
354 |
++ int format, status; |
355 |
++ unsigned long nitems = 0; |
356 |
++ unsigned long extra = 0; |
357 |
++ unsigned char *data = 0; |
358 |
++ QByteArray result = ""; |
359 |
++ status = XGetWindowProperty( QX11Info::display(), w, prop, 0, 10000, |
360 |
++ false, XA_STRING, &type, &format, |
361 |
++ &nitems, &extra, &data ); |
362 |
++ if ( status == Success) { |
363 |
++ if( data ) |
364 |
++ result = (char*)data; |
365 |
++ XFree(data); |
366 |
++ } |
367 |
++ return result; |
368 |
++} |
369 |
++ |
370 |
++static QStringList getQStringListProperty(WId w, Atom prop) |
371 |
++{ |
372 |
++ Atom type; |
373 |
++ int format, status; |
374 |
++ unsigned long nitems = 0; |
375 |
++ unsigned long extra = 0; |
376 |
++ unsigned char *data = 0; |
377 |
++ QStringList result; |
378 |
++ |
379 |
++ status = XGetWindowProperty( QX11Info::display(), w, prop, 0, 10000, |
380 |
++ false, XA_STRING, &type, &format, |
381 |
++ &nitems, &extra, &data ); |
382 |
++ if ( status == Success) { |
383 |
++ if (!data) |
384 |
++ return result; |
385 |
++ for (int i=0; i<(int)nitems; i++) { |
386 |
++ result << QLatin1String( (const char*)data + i ); |
387 |
++ while(data[i]) i++; |
388 |
++ } |
389 |
++ XFree(data); |
390 |
++ } |
391 |
++ return result; |
392 |
++} |
393 |
++ |
394 |
++QStringList KSMServer::windowWmCommand(WId w) |
395 |
++{ |
396 |
++ QStringList ret = getQStringListProperty(w, XA_WM_COMMAND); |
397 |
++ // hacks here |
398 |
++ if( ret.count() == 1 ) { |
399 |
++ QString command = ret.first(); |
400 |
++ // Mozilla is launched using wrapper scripts, so it's launched using "mozilla", |
401 |
++ // but the actual binary is "mozilla-bin" or "<path>/mozilla-bin", and that's what |
402 |
++ // will be also in WM_COMMAND - using this "mozilla-bin" doesn't work at all though |
403 |
++ if( command.endsWith( QStringLiteral( "mozilla-bin" ))) |
404 |
++ return QStringList() << QStringLiteral( "mozilla" ); |
405 |
++ if( command.endsWith( QStringLiteral( "firefox-bin" ))) |
406 |
++ return QStringList() << QStringLiteral( "firefox" ); |
407 |
++ if( command.endsWith( QStringLiteral( "thunderbird-bin" ))) |
408 |
++ return QStringList() << QStringLiteral( "thunderbird" ); |
409 |
++ if( command.endsWith( QStringLiteral( "sunbird-bin" ))) |
410 |
++ return QStringList() << QStringLiteral( "sunbird" ); |
411 |
++ if( command.endsWith( QStringLiteral( "seamonkey-bin" ))) |
412 |
++ return QStringList() << QStringLiteral( "seamonkey" ); |
413 |
++ } |
414 |
++ return ret; |
415 |
++} |
416 |
++ |
417 |
++QString KSMServer::windowWmClientMachine(WId w) |
418 |
++{ |
419 |
++ QByteArray result = getQCStringProperty(w, XA_WM_CLIENT_MACHINE); |
420 |
++ if (result.isEmpty()) { |
421 |
++ result = "localhost"; |
422 |
++ } else { |
423 |
++ // special name for the local machine (localhost) |
424 |
++ char hostnamebuf[80]; |
425 |
++ if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0) { |
426 |
++ hostnamebuf[sizeof(hostnamebuf)-1] = 0; |
427 |
++ if (result == hostnamebuf) |
428 |
++ result = "localhost"; |
429 |
++ if(char *dot = strchr(hostnamebuf, '.')) { |
430 |
++ *dot = '\0'; |
431 |
++ if(result == hostnamebuf) |
432 |
++ result = "localhost"; |
433 |
++ } |
434 |
++ } |
435 |
++ } |
436 |
++ return QLatin1String(result); |
437 |
++} |
438 |
++ |
439 |
++WId KSMServer::windowWmClientLeader(WId w) |
440 |
++{ |
441 |
++ Atom type; |
442 |
++ int format, status; |
443 |
++ unsigned long nitems = 0; |
444 |
++ unsigned long extra = 0; |
445 |
++ unsigned char *data = 0; |
446 |
++ Window result = w; |
447 |
++ status = XGetWindowProperty( QX11Info::display(), w, wm_client_leader, 0, 10000, |
448 |
++ false, XA_WINDOW, &type, &format, |
449 |
++ &nitems, &extra, &data ); |
450 |
++ if (status == Success ) { |
451 |
++ if (data && nitems > 0) |
452 |
++ result = *((Window*) data); |
453 |
++ XFree(data); |
454 |
++ } |
455 |
++ return result; |
456 |
++} |
457 |
++ |
458 |
++ |
459 |
++/* |
460 |
++Returns sessionId for this client, |
461 |
++taken either from its window or from the leader window. |
462 |
++*/ |
463 |
++QByteArray KSMServer::windowSessionId(WId w, WId leader) |
464 |
++{ |
465 |
++ QByteArray result = getQCStringProperty(w, sm_client_id); |
466 |
++ if (result.isEmpty() && leader != (WId)None && leader != w) |
467 |
++ result = getQCStringProperty(leader, sm_client_id); |
468 |
++ return result; |
469 |
++} |
470 |
++#endif |
471 |
+diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp |
472 |
+--- a/ksmserver/server.cpp |
473 |
++++ b/ksmserver/server.cpp |
474 |
+@@ -959,6 +959,7 @@ void KSMServer::storeSession() |
475 |
+ KConfigGroup cg2( config, "General"); |
476 |
+ cg2.writeEntry( "screenCount", ScreenCount(QX11Info::display())); |
477 |
+ |
478 |
++ storeLegacySession(config.data()); |
479 |
+ config->sync(); |
480 |
+ } |
481 |
+ |
482 |
+--- a/ksmserver/server.h |
483 |
++++ b/ksmserver/server.h |
484 |
+@@ -49,5 +49,6 @@ extern "C" { |
485 |
+ #include <KConfigGroup> |
486 |
+ #include <QTimer> |
487 |
++#include <QTime> |
488 |
+ #include <QMap> |
489 |
+ |
490 |
+ |
491 |
+@@ -63,6 +64,16 @@ class KSMClient; |
492 |
+ class OrgKdeKLauncherInterface; |
493 |
+ class QDBusInterface; |
494 |
+ |
495 |
++enum SMType { SM_ERROR, SM_WMCOMMAND, SM_WMSAVEYOURSELF }; |
496 |
++struct SMData |
497 |
++ { |
498 |
++ SMType type; |
499 |
++ QStringList wmCommand; |
500 |
++ QString wmClientMachine; |
501 |
++ QString wmclass1, wmclass2; |
502 |
++ }; |
503 |
++typedef QMap<WId,SMData> WindowMap; |
504 |
++ |
505 |
+ class KSMServer : public QObject |
506 |
+ { |
507 |
+ Q_OBJECT |
508 |
+@@ -147,4 +158,5 @@ private: |
509 |
+ void startKilling(); |
510 |
+ void startKillingSubSession(); |
511 |
++ void performStandardKilling(); |
512 |
+ void completeKilling(); |
513 |
+ void completeKillingSubSession(); |
514 |
+@@ -177,4 +189,13 @@ private: |
515 |
+ void setupXIOErrorHandler(); |
516 |
+ |
517 |
++ void performLegacySessionSave(); |
518 |
++ void storeLegacySession( KConfig* config ); |
519 |
++ void restoreLegacySession( KConfig* config ); |
520 |
++ void restoreLegacySessionInternal( KConfigGroup* config, char sep = ',' ); |
521 |
++ QStringList windowWmCommand(WId w); |
522 |
++ QString windowWmClientMachine(WId w); |
523 |
++ WId windowWmClientLeader(WId w); |
524 |
++ QByteArray windowSessionId(WId w, WId leader); |
525 |
++ |
526 |
+ bool checkStartupSuspend(); |
527 |
+ void finishStartup(); |
528 |
+@@ -184,6 +205,7 @@ private: |
529 |
+ void runShutdownScripts(); |
530 |
+ |
531 |
+- // public D-Bus interface |
532 |
+- public Q_SLOTS: |
533 |
++ // public dcop interface |
534 |
++ |
535 |
++ public Q_SLOTS: //public dcop interface |
536 |
+ void logout( int, int, int ); |
537 |
+ bool canShutdown(); |
538 |
+@@ -256,4 +278,6 @@ private: |
539 |
+ QStringList excludeApps; |
540 |
+ |
541 |
++ WindowMap legacyWindows; |
542 |
++ |
543 |
+ OrgKdeKLauncherInterface* klauncherSignals; |
544 |
+ QDBusInterface* kcminitSignals; |
545 |
+--- a/ksmserver/shutdown.cpp |
546 |
++++ b/ksmserver/shutdown.cpp |
547 |
+@@ -192,5 +192,8 @@ void KSMServer::shutdown( KWorkSpace::ShutdownConfirm confirm, |
548 |
+ state = Shutdown; |
549 |
+ wmPhase1WaitingCount = 0; |
550 |
+- saveType = saveSession ? SmSaveBoth : SmSaveGlobal; |
551 |
++ saveType = saveSession?SmSaveBoth:SmSaveGlobal; |
552 |
++#ifndef NO_LEGACY_SESSION_MANAGEMENT |
553 |
++ performLegacySessionSave(); |
554 |
++#endif |
555 |
+ startProtection(); |
556 |
+ foreach( KSMClient* c, clients ) { |
557 |
+@@ -248,5 +251,8 @@ void KSMServer::saveCurrentSession() |
558 |
+ saveType = SmSaveLocal; |
559 |
+ saveSession = true; |
560 |
++#ifndef NO_LEGACY_SESSION_MANAGEMENT |
561 |
++ performLegacySessionSave(); |
562 |
++#endif |
563 |
+ foreach( KSMClient* c, clients ) { |
564 |
+ c->resetState(); |
565 |
+ if( isWM( c ) ) |
566 |
+@@ -623,5 +629,9 @@ void KSMServer::saveSubSession(const QString &name, QStringList saveAndClose, QS |
567 |
+ saveSession = true; |
568 |
+ sessionGroup = QStringLiteral( "SubSession: " ) + name; |
569 |
+ |
570 |
++#ifndef NO_LEGACY_SESSION_MANAGEMENT |
571 |
++ //performLegacySessionSave(); FIXME |
572 |
++#endif |
573 |
++ |
574 |
+ startProtection(); |
575 |
+ foreach( KSMClient* c, clients ) { |
576 |
+--- a/ksmserver/startup.cpp |
577 |
++++ b/ksmserver/startup.cpp |
578 |
+@@ -446,5 +446,7 @@ void KSMServer::autoStart2() |
579 |
+ } else { |
580 |
+ QTimer::singleShot(0, this, &KSMServer::kcmPhase2Done); |
581 |
+ } |
582 |
++ if( !defaultSession()) |
583 |
++ restoreLegacySession(KSharedConfig::openConfig().data()); |
584 |
+ |
585 |
+ qCDebug(KSMSERVER) << "Starting notification thread"; |
586 |
|
587 |
diff --git a/kde-plasma/plasma-workspace/plasma-workspace-5.6.5.1-r2.ebuild b/kde-plasma/plasma-workspace/plasma-workspace-5.6.5.1-r2.ebuild |
588 |
new file mode 100644 |
589 |
index 0000000..50dd2d0 |
590 |
--- /dev/null |
591 |
+++ b/kde-plasma/plasma-workspace/plasma-workspace-5.6.5.1-r2.ebuild |
592 |
@@ -0,0 +1,168 @@ |
593 |
+# Copyright 1999-2016 Gentoo Foundation |
594 |
+# Distributed under the terms of the GNU General Public License v2 |
595 |
+# $Id$ |
596 |
+ |
597 |
+EAPI=6 |
598 |
+ |
599 |
+KDE_HANDBOOK="forceoptional" |
600 |
+KDE_TEST="forceoptional" |
601 |
+VIRTUALX_REQUIRED="test" |
602 |
+inherit kde5 multilib qmake-utils |
603 |
+ |
604 |
+DESCRIPTION="KDE Plasma workspace" |
605 |
+KEYWORDS="~amd64 ~arm ~x86" |
606 |
+IUSE="+geolocation gps prison qalculate" |
607 |
+ |
608 |
+COMMON_DEPEND=" |
609 |
+ $(add_frameworks_dep baloo) |
610 |
+ $(add_frameworks_dep kactivities) |
611 |
+ $(add_frameworks_dep kauth) |
612 |
+ $(add_frameworks_dep kbookmarks) |
613 |
+ $(add_frameworks_dep kcmutils) |
614 |
+ $(add_frameworks_dep kcompletion) |
615 |
+ $(add_frameworks_dep kconfig) |
616 |
+ $(add_frameworks_dep kconfigwidgets) |
617 |
+ $(add_frameworks_dep kcoreaddons) |
618 |
+ $(add_frameworks_dep kcrash) |
619 |
+ $(add_frameworks_dep kdbusaddons) |
620 |
+ $(add_frameworks_dep kdeclarative) |
621 |
+ $(add_frameworks_dep kdelibs4support) |
622 |
+ $(add_frameworks_dep kdesu) |
623 |
+ $(add_frameworks_dep kglobalaccel) |
624 |
+ $(add_frameworks_dep kguiaddons) |
625 |
+ $(add_frameworks_dep ki18n) |
626 |
+ $(add_frameworks_dep kiconthemes) |
627 |
+ $(add_frameworks_dep kidletime) |
628 |
+ $(add_frameworks_dep kio) |
629 |
+ $(add_frameworks_dep kitemviews) |
630 |
+ $(add_frameworks_dep kjobwidgets) |
631 |
+ $(add_frameworks_dep kjs) |
632 |
+ $(add_frameworks_dep kjsembed) |
633 |
+ $(add_frameworks_dep knewstuff) |
634 |
+ $(add_frameworks_dep knotifications) |
635 |
+ $(add_frameworks_dep knotifyconfig) |
636 |
+ $(add_frameworks_dep kpackage) |
637 |
+ $(add_frameworks_dep krunner) |
638 |
+ $(add_frameworks_dep kservice) |
639 |
+ $(add_frameworks_dep ktexteditor) |
640 |
+ $(add_frameworks_dep ktextwidgets) |
641 |
+ $(add_frameworks_dep kwallet) |
642 |
+ $(add_frameworks_dep kwayland) |
643 |
+ $(add_frameworks_dep kwidgetsaddons) |
644 |
+ $(add_frameworks_dep kwindowsystem) |
645 |
+ $(add_frameworks_dep kxmlgui) |
646 |
+ $(add_frameworks_dep kxmlrpcclient) |
647 |
+ $(add_frameworks_dep plasma) |
648 |
+ $(add_frameworks_dep solid) |
649 |
+ $(add_plasma_dep kscreenlocker) |
650 |
+ $(add_plasma_dep kwin) |
651 |
+ $(add_plasma_dep libksysguard) |
652 |
+ $(add_qt_dep qtconcurrent) |
653 |
+ $(add_qt_dep qtdbus) |
654 |
+ $(add_qt_dep qtdeclarative 'widgets') |
655 |
+ $(add_qt_dep qtgui 'jpeg') |
656 |
+ $(add_qt_dep qtnetwork) |
657 |
+ $(add_qt_dep qtscript) |
658 |
+ $(add_qt_dep qtsql) |
659 |
+ $(add_qt_dep qtwidgets) |
660 |
+ $(add_qt_dep qtx11extras) |
661 |
+ $(add_qt_dep qtxml) |
662 |
+ dev-libs/libdbusmenu-qt[qt5] |
663 |
+ media-libs/phonon[qt5] |
664 |
+ sys-libs/zlib |
665 |
+ x11-libs/libICE |
666 |
+ x11-libs/libSM |
667 |
+ x11-libs/libX11 |
668 |
+ x11-libs/libXau |
669 |
+ x11-libs/libxcb |
670 |
+ x11-libs/libXfixes |
671 |
+ x11-libs/libXrender |
672 |
+ x11-libs/xcb-util |
673 |
+ x11-libs/xcb-util-image |
674 |
+ geolocation? ( $(add_frameworks_dep networkmanager-qt) ) |
675 |
+ gps? ( sci-geosciences/gpsd ) |
676 |
+ prison? ( media-libs/prison:5 ) |
677 |
+ qalculate? ( sci-libs/libqalculate ) |
678 |
+" |
679 |
+RDEPEND="${COMMON_DEPEND} |
680 |
+ $(add_frameworks_dep kded) |
681 |
+ $(add_kdeapps_dep kio-extras) |
682 |
+ $(add_plasma_dep kde-cli-tools) |
683 |
+ $(add_plasma_dep ksysguard) |
684 |
+ $(add_plasma_dep milou) |
685 |
+ $(add_qt_dep qdbus) |
686 |
+ $(add_qt_dep qtgraphicaleffects) |
687 |
+ $(add_qt_dep qtpaths) |
688 |
+ $(add_qt_dep qtquickcontrols 'widgets') |
689 |
+ app-text/iso-codes |
690 |
+ x11-apps/mkfontdir |
691 |
+ x11-apps/xmessage |
692 |
+ x11-apps/xprop |
693 |
+ x11-apps/xrdb |
694 |
+ x11-apps/xset |
695 |
+ x11-apps/xsetroot |
696 |
+ !dev-libs/xembed-sni-proxy |
697 |
+ !kde-base/freespacenotifier:4 |
698 |
+ !kde-base/libtaskmanager:4 |
699 |
+ !kde-base/kcminit:4 |
700 |
+ !kde-base/kdebase-startkde:4 |
701 |
+ !kde-base/klipper:4 |
702 |
+ !kde-base/krunner:4 |
703 |
+ !kde-base/ksmserver:4 |
704 |
+ !kde-base/ksplash:4 |
705 |
+ !kde-base/plasma-workspace:4 |
706 |
+" |
707 |
+DEPEND="${COMMON_DEPEND} |
708 |
+ x11-proto/xproto |
709 |
+" |
710 |
+ |
711 |
+PATCHES=( |
712 |
+ "${FILESDIR}/${PN}-5.4-startkde-script.patch" |
713 |
+ "${FILESDIR}/${PN}-5.6.0-rpath.patch" |
714 |
+ "${FILESDIR}/${PN}-5.6.5-drop-kscreen-dep.patch" |
715 |
+ "${FILESDIR}/${PN}-5.6.5.1-struts.patch" |
716 |
+ "${FILESDIR}/${PN}-5.6.5.1-legacy-session-mgmt.patch" # backport in 5.6 after release |
717 |
+) |
718 |
+ |
719 |
+RESTRICT="test" |
720 |
+ |
721 |
+S=${WORKDIR}/${PN}-5.6.5 |
722 |
+ |
723 |
+src_prepare() { |
724 |
+ kde5_src_prepare |
725 |
+ |
726 |
+ sed -e "s|\`qtpaths|\`$(qt5_get_bindir)/qtpaths|" \ |
727 |
+ -i startkde/startkde.cmake startkde/startplasmacompositor.cmake || die |
728 |
+} |
729 |
+ |
730 |
+src_configure() { |
731 |
+ local mycmakeargs=( |
732 |
+ $(cmake-utils_use_find_package geolocation KF5NetworkManagerQt) |
733 |
+ $(cmake-utils_use_find_package gps libgps) |
734 |
+ $(cmake-utils_use_find_package prison KF5Prison) |
735 |
+ $(cmake-utils_use_find_package qalculate Qalculate) |
736 |
+ ) |
737 |
+ |
738 |
+ kde5_src_configure |
739 |
+} |
740 |
+ |
741 |
+src_install() { |
742 |
+ kde5_src_install |
743 |
+ |
744 |
+ # startup and shutdown scripts |
745 |
+ insinto /etc/plasma/startup |
746 |
+ doins "${FILESDIR}/10-agent-startup.sh" |
747 |
+ |
748 |
+ insinto /etc/plasma/shutdown |
749 |
+ doins "${FILESDIR}/10-agent-shutdown.sh" |
750 |
+} |
751 |
+ |
752 |
+pkg_postinst () { |
753 |
+ kde5_pkg_postinst |
754 |
+ |
755 |
+ echo |
756 |
+ elog "To enable gpg-agent and/or ssh-agent in Plasma sessions," |
757 |
+ elog "edit ${EPREFIX}/etc/plasma/startup/10-agent-startup.sh and" |
758 |
+ elog "${EPREFIX}/etc/plasma/shutdown/10-agent-shutdown.sh" |
759 |
+ echo |
760 |
+} |