1 ////////////////////////////////////////
3 ////////////////////////////////////////
7 ////////////////////////////////////////////////////////////////////////////////
10 atomClientList
= None
,
14 ////////////////////////////////////////////////////////////////////////////////
15 static inline bool isMPlayer (const QString
&name
) {
17 name
.startsWith("mplayer", Qt::CaseInsensitive
) ||
18 name
.startsWith("mplayer2", Qt::CaseInsensitive
) ||
19 name
.startsWith("mpv", Qt::CaseInsensitive
) ||
20 name
.endsWith(" - mpv", Qt::CaseInsensitive
)
25 static inline bool isMPlayerClass (const QString
&name
) {
26 return (name
== "xv" || name
== "gl" || name
== "vdpau");
30 ////////////////////////////////////////////////////////////////////////////////
31 static bool makeFacehugger (Window w
) {
32 //WARNING! this WILL NOT work as expected on our own windows!
33 return XSelectInput(QX11Info::display(), w
, /*SubstructureNotifyMask |*/ StructureNotifyMask
) == Success
;
37 static void dumpWinInfo (const char *msg
, Window w
) {
40 if (w
== None
) return;
41 pw
= X11Tools::windowTransientFor(w
);
42 qDebug() << msg
<< (int)(w
) <<
43 "class:" << X11Tools::windowClass(w
) <<
44 "name:" << X11Tools::windowName(w
) <<
45 "pid:" << X11Tools::windowPID(w
) <<
46 "transientfor:" << pw
;
47 //dumpWinInfo(" parent (tr)", pw);
51 ////////////////////////////////////////////////////////////////////////////////
52 Jrugr::Jrugr (int &argc
, char **argv
) :
53 QApplication(argc
, argv
),
60 mDeskJustChanged(false)
62 if (atomActWin
== None
) atomActWin
= XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True
);
63 if (atomClientList
== None
) atomClientList
= XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", True
);
64 if (atomCurDesk
== None
) atomCurDesk
= XInternAtom(QX11Info::display(), "_NET_CURRENT_DESKTOP", True
);
65 // mandatory to keep it running after closing about dialogs...
66 setQuitOnLastWindowClosed(false);
67 setWindowIcon(QIcon(":/about/jrugr.png"));
69 mCfgFileName
= QDir::homePath()+"/.config/jrugr.cfg";
77 //! \warning the trayIcon *has* to be deleted here to prevent XFreeColormap() free corruption.
82 bool Jrugr::firstStart () {
83 if (!QFile::exists(mCfgFileName
)) {
86 qDebug() << " Jrugr:Config file not found in:" << mCfgFileName
;
87 QSettings
jrugr(mCfgFileName
, QSettings::IniFormat
);
88 QDir
themeDir("/usr/share/jrugr/theme/default");
89 if (themeDir
.exists()) themePath
= themeDir
.path();
90 else themePath
= QCoreApplication::applicationDirPath()+"/theme/default";;
91 jrugr
.beginGroup("Style");
92 mLangThemePath
= themePath
;
93 jrugr
.setValue("path", mLangThemePath
);
94 jrugr
.endGroup(); //Style
101 void Jrugr::startup () {
102 if (firstStart()) configure();
105 QSettings
jrugr(mCfgFileName
, QSettings::IniFormat
, this);
106 jrugr
.beginGroup("Style");
107 mLangThemePath
= jrugr
.value("path").toString()+"/language/";
108 jrugr
.endGroup(); //Style
110 jCfg
= JrugrCfg::load(mCfgFileName
);
112 if (jCfg
->workMode
== USE_XKB
) configureXkb();
113 mMplayerHack
= jCfg
->mplayerHack
;
115 mXkb
= new XKeyboard();
116 mXkb
->groupInfo(mGroupInfo
);
118 connect(mXkb
, SIGNAL(groupChanged(int)), this, SLOT(onGroupChanged(int)), Qt::QueuedConnection
);
119 connect(mXkb
, SIGNAL(layoutChanged()), this, SLOT(onLayoutChanged()), Qt::QueuedConnection
);
120 connect(this, SIGNAL(changeLayout(int)), this, SLOT(onChangeLayout(int)), Qt::QueuedConnection
);
122 connect(this, SIGNAL(activeWindowChanged()), this, SLOT(doActiveWindowChanged()), Qt::QueuedConnection
);
123 connect(this, SIGNAL(activeDesktopChanged()), this, SLOT(doActiveDesktopChanged()), Qt::QueuedConnection
);
124 connect(this, SIGNAL(clientListChanged()), this, SLOT(onClientListChanged()), Qt::QueuedConnection
);
126 #ifdef K8_MPLAYER_HACK
127 mMPFix
= new QTimer(this);
128 mMPFix
->setSingleShot(true);
129 connect(mMPFix
, SIGNAL(timeout()), this, SLOT(onMPFix()), Qt::QueuedConnection
);
134 void Jrugr::initialize () {
135 mXkb
->groupInfo(mGroupInfo
);
137 mMplayerHack
= jCfg
->mplayerHack
;
138 mActiveGroup
= mXkb
->activeGroup();
139 mActiveWindow
= X11Tools::activeWindow();
140 mCurDesk
= X11Tools::activeDesktop();
141 setDeskActiveWindow(mCurDesk
, X11Tools::activeWindow());
143 mTrayIcon
= new QSystemTrayIcon(this);
144 connect(mTrayIcon
, SIGNAL(activated(QSystemTrayIcon::ActivationReason
)), this, SLOT(trayClicked(QSystemTrayIcon::ActivationReason
)));
149 installFacehuggers();
153 void Jrugr::reconfigure () {
154 JrugrCfg
*newConf
= JrugrCfg::load(mCfgFileName
);
160 bool diffGI
= nl
.size() != mGroupInfo
.size();
163 for (int f
= nl
.size()-1; f
>= 0; --f
) if (nl
[f
].name
!= mGroupInfo
[f
].name
|| nl
[f
].sym
!= mGroupInfo
[f
].sym
) { diffGI
= true; break; }
166 if (diffGI
|| newConf
->layouts
!= jCfg
->layouts
|| newConf
->showFlag
!= jCfg
->showFlag
||
167 newConf
->workMode
!= jCfg
->workMode
|| newConf
->switching
!= jCfg
->switching
||
168 mMplayerHack
!= newConf
->mplayerHack
) {
171 mMplayerHack
= jCfg
->mplayerHack
;
182 int Jrugr::setKeyLayout (QString keyConf
) {
183 qDebug() << "Jrugr::setKeyLayout:" << keyConf
;
184 QStringList argument
= keyConf
.split(" ");
185 qDebug() << " Jrugr:setxkbmap argumetns:" << argument
;
186 int result
= QProcess::execute("setxkbmap", argument
);
187 qDebug() << " Jrugr:setxkbmap result:" << result
;
192 void Jrugr::configureXkb () {
193 QString layout
, variant
, option
;
194 QString model
= jCfg
->model
;
196 for (int f
= 0; f
< jCfg
->layouts
.count(); ++f
) {
197 layout
+= jCfg
->layouts
[f
].layout
;
198 variant
+= jCfg
->layouts
[f
].variant
;
199 if (f
< jCfg
->layouts
.count()-1) { layout
+= ','; variant
+= ','; }
201 option
= jCfg
->options
.join(",");
202 qDebug() << "Set layout:" << layout
;
203 if (!(model
.isEmpty() || model
.isNull()) && !(layout
.isEmpty() || layout
.isNull())) {
204 QString args
= "-model "+model
+" -layout "+layout
;
205 QString tmp
= variant
;
206 if (!variant
.isNull() && !variant
.isEmpty() && !tmp
.remove(",").isEmpty()) args
+=" -variant "+variant
;
207 if (!option
.isNull() && !option
.isEmpty()) args
+=" -option "+option
;
208 qDebug() << " Jrugr:XKB args " << args
;
209 if (setKeyLayout(args
) == QProcess::CrashExit
) {
210 qDebug() << " Jrugr:XKB isn`t set";
211 qDebug() << " Jrugr:------------------------------";
214 qDebug() << " Jrugr:XKB set";
219 void Jrugr::configure () {
220 JrugrConfigForm
*mCfgForm
= new JrugrConfigForm(mCfgFileName
);
221 connect(mCfgForm
, SIGNAL(saveConfig()), SLOT(reconfigure()));
222 mCfgForm
->exec(); // the form will die on closing
226 int Jrugr::layIndex (Window w
, const QString
&propname
, bool unknownIsZero
) const {
227 QString
alay(X11Tools::getjprop(w
, propname
.toUtf8().constData()));
229 if (alay
.size() > 0) {
230 int idx
= XKeyboard::findBySym(mGroupInfo
, alay
);
232 qDebug() << "Win:" << w
<< "alay:" << alay
<< "idx:" << idx
;
235 return unknownIsZero
? 0 : -1;
239 bool Jrugr::isKnownWindow (Window w
) const {
240 return mKnownWindows
.contains(w
);
244 bool Jrugr::isKnownApp (Window w
) const {
245 return mKnownApps
.contains(X11Tools::appWindow(w
));
249 WinInfo
*Jrugr::findWindowInfo (Window w
) {
250 return mKnownWindows
.value(w
, 0);
254 // find application info for the given window
255 WinInfo
*Jrugr::findAppInfo (Window w
) {
256 return mKnownApps
.value(X11Tools::appWindow(w
), 0);
260 int Jrugr::desktopLayout (int desk
) const {
261 if (desk
< 0 || desk
>= mDeskLangs
.size()) return 0;
262 return mDeskLangs
.at(desk
);
266 void Jrugr::setDesktopLayout (int desk
, int group
) {
267 if (desk
>= 0 && group
< mGroupInfo
.size()) {
268 X11Tools::setjprop(None
, QString("DESK%1_LAYOUT").arg(desk
), mGroupInfo
[group
].sym
);
270 if (desk
< 0 || desk
> 42) return; // invalid desktop number
271 while (mDeskLangs
.size() <= desk
) {
272 QString
ln(QString("DESK%1_LAYOUT").arg(mDeskLangs
.size()));
273 int idx
= layIndex(None
, ln
.toLatin1().constData(), true);
275 //qDebug() << "desk:" << mDeskLangs.size() << "layidx:" << idx;
276 if (group
< mGroupInfo
.size()) X11Tools::setjprop(None
, ln
, mGroupInfo
[group
].sym
);
279 mDeskLangs
[desk
] = group
;
283 Window
Jrugr::deskActiveWindow (int desk
) {
284 if (desk
< 0 || desk
>= mDeskActiveWindows
.size()) return None
;
285 return mDeskActiveWindows
.at(desk
);
289 void Jrugr::setDeskActiveWindow (int desk
, Window w
) {
290 if (desk
< 0 || desk
> 42) return; // invalid desktop number
291 while (mDeskActiveWindows
.size() <= desk
) mDeskActiveWindows
<< None
;
292 mDeskActiveWindows
[desk
] = w
;
294 qDebug() << "DESK:" << desk
<<
295 "class:" << X11Tools::windowClass(w
) <<
296 "name:" << X11Tools::windowName(w
);
298 qDebug() << "DESK:" << desk
<< "None";
303 void Jrugr::installFacehuggers () {
304 QX11WindowList wl
= X11Tools::topLevelWindows();
308 //QWidgetList twl = QApplication::allWidgets();
309 QWidgetList twl
= QApplication::topLevelWidgets();
310 foreach (QWidget
*wd
, twl
) {
311 WId w
= wd
->effectiveWinId();
312 if (w
!= None
) qtwl
<< w
;
316 for (int f
= 0; f
< wl
.size(); ++f
) {
317 if (wl
[f
] != None
&& !qtwl
.contains(wl
[f
]) && !isKnownWindow(wl
[f
])) {
318 WinInfo
*wi
= new WinInfo
;
321 wi
->appWindow
= X11Tools::appWindow(wl
[f
]);
322 wi
->layout
= layIndex(wi
->w
, "WIN_LAYOUT", true);
323 if (wi
->layout
< mGroupInfo
.size()) X11Tools::setjprop(wi
->w
, "WIN_LAYOUT", mGroupInfo
[wi
->layout
].sym
);
324 mKnownWindows
[wl
[f
]] = wi
;
325 makeFacehugger(wi
->w
);
327 if (wi
->appWindow
== wi
->w
&& !isKnownApp(wi
->w
)) {
328 WinInfo
*w2
= new WinInfo
;
330 w2
->appWindow
= w2
->w
= wi
->w
;
331 w2
->layout
= layIndex(w2
->w
, "APP_LAYOUT", false);
332 if (w2
->layout
< 0) w2
->layout
= wi
->layout
;
333 if (w2
->layout
< mGroupInfo
.size()) X11Tools::setjprop(w2
->w
, "APP_LAYOUT", mGroupInfo
[w2
->layout
].sym
);
334 mKnownApps
[w2
->w
] = w2
;
341 void Jrugr::doActiveWindowChanged () {
342 //qDebug() << "doActiveWindowChanged";
343 onActiveWindowChanged(X11Tools::activeWindow());
347 void Jrugr::doActiveDesktopChanged () {
348 //qDebug() << "doActiveDesktopChanged";
349 onActiveDesktopChanged(X11Tools::activeDesktop());
353 void Jrugr::onLayoutChanged () {
354 qDebug()<<"Jrugr::onLayoutChanged : reconfig";
356 qDebug()<<"Jrugr::onLayoutChanged : done";
360 QIcon
Jrugr::langIcon (const QString
&lsym
, int wdt
, int hgt
, bool noFlag
) {
362 QString path
= mLangThemePath
+fixLayoutName(lsym
, jCfg
->useSU
);
363 QString SVGfile
= path
+".svg";
365 if (QFile::exists(SVGfile
)) {
366 QSvgRenderer
flagSVG(SVGfile
);
367 if (flagSVG
.isValid()) {
368 QPixmap
pix(wdt
, hgt
);
371 flagSVG
.render(&painter
, QRectF(0, 0, wdt
, hgt
));
377 QString PNGfile
= path
+".png";
378 if (QFile::exists(PNGfile
)) {
379 return QIcon(PNGfile
);
384 qDebug() << ":::" << lsym
;
385 QFont
font("Helvetica [Cronyx]", 15); //FIXME: should be configurable
386 //QFont font("Tahoma", 15);
388 font
.setLetterSpacing(QFont::PercentageSpacing
, 120);
389 QPixmap
pix(lsym
.length()*20, 26);
392 painter
.setFont(font
);
393 painter
.fillRect(pix
.rect(), Qt::darkGray
);
394 painter
.setPen(Qt::white
);
395 painter
.drawText(pix
.rect(), Qt::AlignVCenter
|Qt::AlignCenter
, lsym
);
402 void Jrugr::createMenu () {
404 mTrayMenu
= new QMenu();
405 connect(mTrayMenu
, SIGNAL(triggered(QAction
*)), SLOT(actionsActivate(QAction
*)));
410 for (int index
= 0; index
< mGroupInfo
.size(); ++index
) {
411 QString lname
= mGroupInfo
[index
].name
, lsym
= mGroupInfo
[index
].sym
;
413 QAction
*act
= new QAction(lname
, this);
414 act
->setIcon(langIcon(lsym
));
416 mTrayMenu
->addAction(act
);
419 mTrayMenu
->addSeparator();
420 QAction
*config
= new QAction(tr("Configure"), this);
421 config
->setData("configure");
422 mTrayMenu
->addAction(config
);
424 mTrayMenu
->addSeparator();
425 QAction
*about_jrugr
= new QAction(tr("About Jrugr"), this);
426 about_jrugr
->setData("about_jrugr");
427 mTrayMenu
->addAction(about_jrugr
);
429 QAction
*about_qt
= new QAction(tr("About Qt"), this);
430 about_qt
->setData("about_qt");
431 mTrayMenu
->addAction(about_qt
);
433 mTrayMenu
->addSeparator();
434 QAction
*jrugrExit
= new QAction(tr("Exit"), this);
435 jrugrExit
->setData("exit");
436 mTrayMenu
->addAction(jrugrExit
);
440 void Jrugr::buildIcon () {
441 if (!mTrayIcon
) return;
442 mTrayIcon
->setIcon(langIcon(mGroupInfo
[mActiveGroup
].sym
, 32, 22, !jCfg
->showFlag
));
443 mTrayIcon
->setToolTip(mGroupInfo
[mActiveGroup
].name
);
444 if (mTrayMenu
) mTrayIcon
->setContextMenu(mTrayMenu
);
449 void Jrugr::trayClicked (QSystemTrayIcon::ActivationReason reason
) {
451 case QSystemTrayIcon::Trigger
: setNextGroup(); break;
452 case QSystemTrayIcon::DoubleClick
: setNextGroup(); break;
453 case QSystemTrayIcon::MiddleClick
: setPrevGroup(); break;
459 // new layout activated; fix all necessary shit
460 void Jrugr::onGroupChanged (int index
) {
461 qDebug() << "Jrugr::onGroupChanged: index:" << index
;
462 mActiveGroup
= index
;
465 if (mActiveWindow
!= None
) {
466 WinInfo
*wi
= findWindowInfo(mActiveWindow
);
469 qDebug() << "new window";
470 installFacehuggers();
471 wi
= findWindowInfo(mActiveWindow
);
475 qDebug() << "fixing window layout";
477 if (index
< mGroupInfo
.size()) X11Tools::setjprop(wi
->w
, "WIN_LAYOUT", mGroupInfo
[index
].sym
);
478 if (jCfg
->switching
== APP_LAYOUT
) {
479 wi
= findAppInfo(mActiveWindow
);
481 qDebug() << "fixing app layout";
483 if (index
< mGroupInfo
.size()) X11Tools::setjprop(wi
->w
, "APP_LAYOUT", mGroupInfo
[index
].sym
);
485 qWarning() << "***APP SHIT!***";
489 qWarning() << "***WINDOW SHIT!***";
493 setDesktopLayout(X11Tools::activeDesktop(), mActiveGroup
);
497 void Jrugr::setNextGroup () {
498 mXkb
->setActiveGroup(mActiveGroup
+1>=mGroupInfo
.size()?0:mActiveGroup
+1);
502 void Jrugr::setPrevGroup () {
503 mXkb
->setActiveGroup(mActiveGroup
-1<0?mGroupInfo
.size()-1:mActiveGroup
-1);
507 void Jrugr::windowDies (Window w
) {
509 qDebug("**************************** FACEHUGGER PARENT DIES ****************************");
513 QWIHashMutableIterator
i(mKnownWindows
);
514 while (i
.hasNext()) {
515 WinInfo
*wi
= i
.next().value();
519 if (wi
->w
== wi
->appWindow
) {
520 if (appW
== None
) appW
= wi
->w
;
521 else if (appW
!= wi
->w
) qWarning("*** WTF?! ***");
528 // remove application
529 QWIHashMutableIterator
i(mKnownApps
);
530 while (i
.hasNext()) {
531 WinInfo
*wi
= i
.next().value();
543 void Jrugr::onChangeLayout (int index
) {
544 qDebug() << "Jrugr::changeLayout:" << index
;
545 mXkb
->setActiveGroup(index
);
549 void Jrugr::actionsActivate (QAction
*action
) {
550 QString cmd
= action
->data().toString();
552 qDebug() << "Jrugr::actionsActivate() command" << cmd
;
553 if (cmd
== "configure") {
555 } else if (cmd
== "about_qt") {
557 } else if (cmd
== "about_jrugr") {
558 QMessageBox::about(0,
560 tr("<h2>Jrugr, the keyboard layout switcher</h2>"
561 "<b>Version</b>: %1<p>"
562 "Gui tool to configure XKB extentions of X server.<p>"
563 "(c) 2009-2011 Fedor Chelbarakh, Petr Vanek, Ketmar").arg(JRUGR_VERSION
));
564 } else if (cmd
== "exit") {
565 qDebug() << "Jrugr::actionsActivate() exit";
568 for (int f
= mGroupInfo
.size()-1; f
>= 0; --f
) {
569 if (cmd
== mGroupInfo
[f
].name
) {
570 emit
changeLayout(f
);
578 #ifdef K8_MPLAYER_HACK
579 static bool isMPlayer (Window w
) {
581 if (X11Tools::windowDesktop(w
) == -1 && isMPlayerClass(X11Tools::windowClass(w
))) {
582 QString name
= X11Tools::windowName(w
).toLower();
583 if (isMPlayer(name
)) return true;
590 static QX11WindowList
getPossibleActives (Window mpw
) {
591 QX11WindowList res
, wl
= X11Tools::topLevelWindowStack();
592 int desk
= X11Tools::activeDesktop();
595 qDebug() << "looking for window to refocus...";
596 for (int f
= 0; f
< wl
.size(); ++f
) {
598 int wd
= X11Tools::windowDesktop(w
);
601 // skip 'special' windows
602 QStringList sl
= X11Tools::windowStateNames(w
);
603 if (sl
.indexOf("_NET_WM_STATE_STICKY") < 0 &&
604 sl
.indexOf("_NET_WM_STATE_HIDDEN") < 0 &&
605 sl
.indexOf("_NET_WM_STATE_SHADED") < 0 &&
606 sl
.indexOf("_NET_WM_STATE_SKIP_TASKBAR") < 0 &&
607 sl
.indexOf("_NET_WM_STATE_ABOVE") < 0 &&
608 sl
.indexOf("_NET_WM_STATE_BELOW") < 0) {
609 QString
cls(X11Tools::windowClass(w
));
610 if (isMPlayerClass(cls
)) {
611 QString
name(X11Tools::windowName(w
).toLower());
612 if (isMPlayer(name
)) continue;
614 if (wine
== None
&& cls
== "explorer.exe") {
616 qDebug() << " WINE:" << cls
;
618 //FIXME: this will not work as expected!
619 if (f
> 0 && wl
.at(f
-1) == mpw
) {
624 qDebug() << " NORM:" << cls
;
630 if (wine
!= None
) res
<< wine
;
636 bool Jrugr::deactivateMPlayer () {
637 qDebug() << "onActiveWindowChanged";
638 Window aw
= X11Tools::activeWindow();
639 bool changeFocus
= false;
642 if (X11Tools::windowDesktop(aw
) == -1 && isMPlayerClass(X11Tools::windowClass(aw
))) {
643 QString name
= X11Tools::windowName(aw
).toLower();
644 if (isMPlayer(name
)) {
645 qDebug() << "MPlayer hack!";
650 qDebug() << "Empty window hack!";
655 // find previous window
656 Window pw
= deskActiveWindow(mCurDesk
);
657 int dsk
= X11Tools::windowDesktop(pw
);
658 if (pw
== None
|| isMPlayer(pw
) || (dsk
!= -1 && dsk
!= mCurDesk
)) {
659 QX11WindowList wl
= getPossibleActives(aw
);
661 if (wl
.size() > 0) pw
= wl
.at(wl
.size()-1); else pw
= None
;
664 qDebug() << "CHANGING FOCUS!" <<
665 "class:" << X11Tools::windowClass(pw
) <<
666 "name:" << X11Tools::windowName(pw
) <<
667 "pid:" << X11Tools::windowPID(pw
);
669 X11Tools::setActiveWindow(pw
);
677 void Jrugr::onMPFix () {
678 if (!deactivateMPlayer()) setDeskActiveWindow(mCurDesk
, mActiveWindow
);
683 void Jrugr::onActiveWindowChanged (Window w
) {
684 qDebug() << "onActiveWindowChanged";
686 #ifdef K8_MPLAYER_HACK
687 if (mDeskJustChanged
) {
688 //deactivateMPlayer();
690 mMPFix
->start(MPLAYER_HACK_TIMEOUT
);
692 mDeskJustChanged
= false;
695 setDeskActiveWindow(mCurDesk
, w
);
697 mActiveWindow
= None
;
698 qDebug() << "new active window: NONE";
701 qDebug() << "new active window:" << (int)w
<< "desktop:" << X11Tools::windowDesktop(w
);
702 dumpWinInfo("new active window:", w
);
704 if (mDeskJustChanged
) {
705 qDebug() << "*** mDeskJustChanged ***";
706 mDeskJustChanged
= false;
707 #ifdef K8_MPLAYER_HACK
708 if (mMplayerHack
&& isMPlayer(w
)) {
709 //mMPFix->start(MPLAYER_HACK_TIMEOUT);
710 if (deactivateMPlayer()) return;
715 #ifdef K8_MPLAYER_HACK
716 if (!mMplayerHack
|| !isMPlayer(w
))
718 setDeskActiveWindow(mCurDesk
, w
);
720 WinInfo
*wi
= findWindowInfo(w
), *aw
;
722 qDebug() << "new window";
723 installFacehuggers();
724 wi
= findWindowInfo(w
);
727 switch (jCfg
->switching
) {
729 if ((aw
= findAppInfo(w
)) != findAppInfo(mActiveWindow
)) {
730 qDebug("application changed!");
732 if (aw
->layout
!= mActiveGroup
) {
733 qDebug("enforcing layout %d", aw
->layout
);
734 emit
changeLayout(aw
->layout
);
737 qWarning("*** APP SHIT! ***");
742 if (wi
->layout
!= mActiveGroup
) {
743 qDebug("enforcing layout %d", wi
->layout
);
744 emit
changeLayout(wi
->layout
);
755 void Jrugr::onClientListChanged () {
756 qDebug() << "onClientListChanged";
757 installFacehuggers();
761 void Jrugr::onActiveDesktopChanged (int desk
) {
762 qDebug() << "onActiveDesktopChanged:" << desk
;
763 mDeskJustChanged
= true;
764 #ifdef K8_MPLAYER_HACK
765 //if (deactivateMPlayer()) mDeskJustChanged = false;
767 mMPFix
->start(MPLAYER_HACK_TIMEOUT
);
770 if (jCfg
->switching
== DESK_LAYOUT
&& mCurDesk
!= desk
) {
771 int ll
= desktopLayout(desk
);
772 setDesktopLayout(desk
, ll
); // expand desktop list
773 if (ll
!= mActiveGroup
) {
774 qDebug("enforce layout %d for desktop %d", ll
, desk
);
775 emit
changeLayout(mDeskLangs
.at(desk
));
782 bool Jrugr::x11EventFilter (XEvent
*event
) {
784 //qDebug() << "Jrugr::x11EventFilter:" << x11EventName(event);
785 switch (event
->type
) {
787 windowDies(event
->xdestroywindow
.window
);
790 if (event
->xproperty
.state
== PropertyNewValue
) {
791 if (atomActWin
!= None
&& event
->xproperty
.atom
== atomActWin
) {
792 //qDebug() << "emit: activeWindowChanged";
793 emit
activeWindowChanged();
795 if (atomCurDesk
!= None
&& event
->xproperty
.atom
== atomCurDesk
) {
796 //qDebug() << "emit: activeDesktopChanged";
797 emit
activeDesktopChanged();
799 if (atomClientList
!= None
&& event
->xproperty
.atom
== atomClientList
) {
800 qDebug() << "emit: clientListChanged";
801 emit
clientListChanged();
804 //qDebug() << "PropertyNotify complete";
807 if (mXkb
) mXkb
->processEvent(event
);
811 return false; // normal dispatching