storing layouts in window properties and restoring when Jrugr restarted
[jrugr.git] / src / jrugr.cpp
blob8758be4834657a31304bb3308a5dea26e27db7df
1 ////////////////////////////////////////
2 // Copyright : GPL //
3 ////////////////////////////////////////
4 #include "jrugr.h"
7 ////////////////////////////////////////////////////////////////////////////////
8 static Atom
9 atomActWin = None,
10 atomClientList = None,
11 atomCurDesk = None;
14 ////////////////////////////////////////////////////////////////////////////////
15 static bool makeFacehugger (Window w) {
16 //WARNING! this WILL NOT work as expected on our own windows!
17 return XSelectInput(QX11Info::display(), w, /*SubstructureNotifyMask |*/ StructureNotifyMask) == Success;
21 static void dumpWinInfo (const char *msg, Window w) {
22 Window pw;
24 if (w == None) return;
25 pw = X11Tools::windowTransientFor(w);
26 qDebug() << msg << (int)(w) <<
27 "class:" << X11Tools::windowClass(w) <<
28 "name:" << X11Tools::windowName(w) <<
29 "pid:" << X11Tools::windowPID(w) <<
30 "transientfor:" << pw;
31 //dumpWinInfo(" parent (tr)", pw);
35 ////////////////////////////////////////////////////////////////////////////////
36 Jrugr::Jrugr (int &argc, char **argv) :
37 QApplication(argc, argv),
39 mActiveGroup(0),
40 mXkb(0),
41 mTrayIcon(0),
42 mTrayMenu(0),
43 jCfg(0),
44 mDeskJustChanged(false)
46 if (atomActWin == None) atomActWin = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True);
47 if (atomClientList == None) atomClientList = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", True);
48 if (atomCurDesk == None) atomCurDesk = XInternAtom(QX11Info::display(), "_NET_CURRENT_DESKTOP", True);
49 // mandatory to keep it running after closing about dialogs...
50 setQuitOnLastWindowClosed(false);
51 setWindowIcon(QIcon(":/about/jrugr.png"));
53 mCfgFileName = QDir::homePath()+"/.config/jrugr.cfg";
57 Jrugr::~Jrugr () {
58 delete mXkb;
59 delete mTrayMenu;
60 delete jCfg;
61 //! \warning the trayIcon *has* to be deleted here to prevent XFreeColormap() free corruption.
62 delete mTrayIcon;
66 bool Jrugr::firstStart () {
67 if (!QFile::exists(mCfgFileName)) {
68 QString themePath;
70 qDebug() << " Jrugr:Config file not found in:" << mCfgFileName;
71 QSettings jrugr(mCfgFileName, QSettings::IniFormat);
72 QDir themeDir("/usr/share/jrugr/theme/default");
73 if (themeDir.exists()) themePath = themeDir.path();
74 else themePath = QCoreApplication::applicationDirPath()+"/theme/default";;
75 jrugr.beginGroup("Style");
76 mLangThemePath = themePath;
77 jrugr.setValue("path", mLangThemePath);
78 jrugr.endGroup(); //Style
79 return true;
81 return false;
85 void Jrugr::startup () {
86 if (firstStart()) configure();
89 QSettings jrugr(mCfgFileName, QSettings::IniFormat, this);
90 jrugr.beginGroup("Style");
91 mLangThemePath = jrugr.value("path").toString()+"/language/";
92 jrugr.endGroup(); //Style
94 jCfg = JrugrCfg::load(mCfgFileName);
95 if (!jCfg) abort();
96 if (jCfg->workMode == USE_XKB) configureXkb();
97 mMplayerHack = jCfg->mplayerHack;
99 mXkb = new XKeyboard();
100 mXkb->groupInfo(mGroupInfo);
102 connect(mXkb, SIGNAL(groupChanged(int)), this, SLOT(onGroupChanged(int)), Qt::QueuedConnection);
103 connect(mXkb, SIGNAL(layoutChanged()), this, SLOT(onLayoutChanged()), Qt::QueuedConnection);
104 connect(this, SIGNAL(changeLayout(int)), this, SLOT(onChangeLayout(int)), Qt::QueuedConnection);
106 connect(this, SIGNAL(activeWindowChanged()), this, SLOT(doActiveWindowChanged()), Qt::QueuedConnection);
107 connect(this, SIGNAL(activeDesktopChanged()), this, SLOT(doActiveDesktopChanged()), Qt::QueuedConnection);
108 connect(this, SIGNAL(clientListChanged()), this, SLOT(onClientListChanged()), Qt::QueuedConnection);
110 #ifdef K8_MPLAYER_HACK
111 mMPFix = new QTimer(this);
112 mMPFix->setSingleShot(true);
113 connect(mMPFix, SIGNAL(timeout()), this, SLOT(onMPFix()), Qt::QueuedConnection);
114 #endif
118 void Jrugr::initialize () {
119 mXkb->groupInfo(mGroupInfo);
121 mMplayerHack = jCfg->mplayerHack;
122 mActiveGroup = mXkb->activeGroup();
123 mActiveWindow = X11Tools::activeWindow();
124 mCurDesk = X11Tools::activeDesktop();
125 setDeskActiveWindow(mCurDesk, X11Tools::activeWindow());
127 mTrayIcon = new QSystemTrayIcon(this);
128 connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClicked(QSystemTrayIcon::ActivationReason)));
130 createMenu();
131 buildIcon();
133 installFacehuggers();
137 void Jrugr::reconfigure () {
138 JrugrCfg *newConf = JrugrCfg::load(mCfgFileName);
140 if (newConf) {
141 QXkbLayoutList nl;
143 mXkb->groupInfo(nl);
144 bool diffGI = nl.size() != mGroupInfo.size();
146 if (!diffGI) {
147 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; }
150 if (diffGI || newConf->layouts != jCfg->layouts || newConf->showFlag != jCfg->showFlag ||
151 newConf->workMode != jCfg->workMode || newConf->switching != jCfg->switching ||
152 mMplayerHack != newConf->mplayerHack) {
153 delete jCfg;
154 jCfg = newConf;
155 mMplayerHack = jCfg->mplayerHack;
156 mGroupInfo = nl;
157 createMenu();
158 buildIcon();
159 } else {
160 delete newConf;
166 int Jrugr::setKeyLayout (QString keyConf) {
167 qDebug() << "Jrugr::setKeyLayout:" << keyConf;
168 QStringList argument = keyConf.split(" ");
169 qDebug() << " Jrugr:setxkbmap argumetns:" << argument;
170 int result = QProcess::execute("setxkbmap", argument);
171 qDebug() << " Jrugr:setxkbmap result:" << result;
172 return result;
176 void Jrugr::configureXkb () {
177 QString layout, variant, option;
178 QString model = jCfg->model;
180 for (int f = 0; f < jCfg->layouts.count(); ++f) {
181 layout += jCfg->layouts[f].layout;
182 variant += jCfg->layouts[f].variant;
183 if (f < jCfg->layouts.count()-1) { layout += ','; variant += ','; }
185 option = jCfg->options.join(",");
186 qDebug() << "Set layout:" << layout;
187 if (!(model.isEmpty() || model.isNull()) && !(layout.isEmpty() || layout.isNull())) {
188 QString args = "-model "+model+" -layout "+layout;
189 QString tmp = variant;
190 if (!variant.isNull() && !variant.isEmpty() && !tmp.remove(",").isEmpty()) args +=" -variant "+variant;
191 if (!option.isNull() && !option.isEmpty()) args +=" -option "+option;
192 qDebug() << " Jrugr:XKB args " << args;
193 if (setKeyLayout(args) == QProcess::CrashExit) {
194 qDebug() << " Jrugr:XKB isn`t set";
195 qDebug() << " Jrugr:------------------------------";
196 return;
198 qDebug() << " Jrugr:XKB set";
203 void Jrugr::configure () {
204 JrugrConfigForm *mCfgForm = new JrugrConfigForm(mCfgFileName);
205 connect(mCfgForm, SIGNAL(saveConfig()), SLOT(reconfigure()));
206 mCfgForm->exec(); // the form will die on closing
210 int Jrugr::layIndex (Window w, const QString &propname, bool unknownIsZero) const {
211 QString alay(X11Tools::getjprop(w, propname.toUtf8().constData()));
213 if (alay.size() > 0) {
214 int idx = XKeyboard::findBySym(mGroupInfo, alay);
216 qDebug() << "Win:" << w << "alay:" << alay << "idx:" << idx;
217 return idx;
219 return unknownIsZero ? 0 : -1;
223 bool Jrugr::isKnownWindow (Window w) const {
224 return mKnownWindows.contains(w);
228 bool Jrugr::isKnownApp (Window w) const {
229 return mKnownApps.contains(X11Tools::appWindow(w));
233 WinInfo *Jrugr::findWindowInfo (Window w) {
234 return mKnownWindows.value(w, 0);
238 // find application info for the given window
239 WinInfo *Jrugr::findAppInfo (Window w) {
240 return mKnownApps.value(X11Tools::appWindow(w), 0);
244 int Jrugr::desktopLayout (int desk) const {
245 if (desk < 0 || desk >= mDeskLangs.size()) return 0;
246 return mDeskLangs.at(desk);
250 void Jrugr::setDesktopLayout (int desk, int group) {
251 if (desk >= 0 && group < mGroupInfo.size()) {
252 X11Tools::setjprop(None, QString("DESK%1_LAYOUT").arg(desk), mGroupInfo[group].sym);
254 if (desk < 0 || desk > 42) return; // invalid desktop number
255 while (mDeskLangs.size() <= desk) {
256 QString ln(QString("DESK%1_LAYOUT").arg(mDeskLangs.size()));
257 int idx = layIndex(None, ln.toLatin1().constData(), true);
259 //qDebug() << "desk:" << mDeskLangs.size() << "layidx:" << idx;
260 if (group < mGroupInfo.size()) X11Tools::setjprop(None, ln, mGroupInfo[group].sym);
261 mDeskLangs << idx;
263 mDeskLangs[desk] = group;
267 Window Jrugr::deskActiveWindow (int desk) {
268 if (desk < 0 || desk >= mDeskActiveWindows.size()) return None;
269 return mDeskActiveWindows.at(desk);
273 void Jrugr::setDeskActiveWindow (int desk, Window w) {
274 if (desk < 0 || desk > 42) return; // invalid desktop number
275 while (mDeskActiveWindows.size() <= desk) mDeskActiveWindows << None;
276 mDeskActiveWindows[desk] = w;
277 if (w != None) {
278 qDebug() << "DESK:" << desk <<
279 "class:" << X11Tools::windowClass(w) <<
280 "name:" << X11Tools::windowName(w);
281 } else {
282 qDebug() << "DESK:" << desk << "None";
287 void Jrugr::installFacehuggers () {
288 QX11WindowList wl = X11Tools::topLevelWindows();
289 QSet<WId> qtwl;
292 //QWidgetList twl = QApplication::allWidgets();
293 QWidgetList twl = QApplication::topLevelWidgets();
294 foreach (QWidget *wd, twl) {
295 WId w = wd->effectiveWinId();
296 if (w != None) qtwl << w;
300 for (int f = 0; f < wl.size(); ++f) {
301 if (wl[f] != None && !qtwl.contains(wl[f]) && !isKnownWindow(wl[f])) {
302 WinInfo *wi = new WinInfo;
304 wi->w = wl[f];
305 wi->appWindow = X11Tools::appWindow(wl[f]);
306 wi->layout = layIndex(wi->w, "WIN_LAYOUT", true);
307 if (wi->layout < mGroupInfo.size()) X11Tools::setjprop(wi->w, "WIN_LAYOUT", mGroupInfo[wi->layout].sym);
308 mKnownWindows[wl[f]] = wi;
309 makeFacehugger(wi->w);
311 if (wi->appWindow == wi->w && !isKnownApp(wi->w)) {
312 WinInfo *w2 = new WinInfo;
314 w2->appWindow = w2->w = wi->w;
315 w2->layout = layIndex(w2->w, "APP_LAYOUT", false);
316 if (w2->layout < 0) w2->layout = wi->layout;
317 if (w2->layout < mGroupInfo.size()) X11Tools::setjprop(w2->w, "APP_LAYOUT", mGroupInfo[w2->layout].sym);
318 mKnownApps[w2->w] = w2;
325 void Jrugr::doActiveWindowChanged () {
326 //qDebug() << "doActiveWindowChanged";
327 onActiveWindowChanged(X11Tools::activeWindow());
331 void Jrugr::doActiveDesktopChanged () {
332 //qDebug() << "doActiveDesktopChanged";
333 onActiveDesktopChanged(X11Tools::activeDesktop());
337 void Jrugr::onLayoutChanged () {
338 qDebug()<<"Jrugr::onLayoutChanged : reconfig";
339 reconfigure();
340 qDebug()<<"Jrugr::onLayoutChanged : done";
344 QIcon Jrugr::langIcon (const QString &lsym, int wdt, int hgt, bool noFlag) {
345 if (!noFlag) {
346 QString path = mLangThemePath+fixLayoutName(lsym, jCfg->useSU);
347 QString SVGfile = path+".svg";
349 if (QFile::exists(SVGfile)) {
350 QSvgRenderer flagSVG(SVGfile);
351 if (flagSVG.isValid()) {
352 QPixmap pix(wdt, hgt);
353 QPainter painter;
354 painter.begin(&pix);
355 flagSVG.render(&painter, QRectF(0, 0, wdt, hgt));
356 painter.end();
357 return QIcon(pix);
361 QString PNGfile = path+".png";
362 if (QFile::exists(PNGfile)) {
363 return QIcon(PNGfile);
368 qDebug() << ":::" << lsym;
369 QFont font("Helvetica [Cronyx]", 15); //FIXME: should be configurable
370 //QFont font("Tahoma", 15);
371 font.setBold(true);
372 font.setLetterSpacing(QFont::PercentageSpacing, 120);
373 QPixmap pix(lsym.length()*20, 26);
374 QPainter painter;
375 painter.begin(&pix);
376 painter.setFont(font);
377 painter.fillRect(pix.rect(), Qt::darkGray);
378 painter.setPen(Qt::white);
379 painter.drawText(pix.rect(), Qt::AlignVCenter|Qt::AlignCenter, lsym);
380 painter.end();
381 return QIcon(pix);
386 void Jrugr::createMenu () {
387 if (!mTrayMenu) {
388 mTrayMenu = new QMenu();
389 connect(mTrayMenu, SIGNAL(triggered(QAction *)), SLOT(actionsActivate(QAction *)));
390 } else {
391 mTrayMenu->clear();
394 for (int index = 0; index < mGroupInfo.size(); ++index) {
395 QString lname = mGroupInfo[index].name, lsym = mGroupInfo[index].sym;
397 QAction *act = new QAction(lname, this);
398 act->setIcon(langIcon(lsym));
399 act->setData(lname);
400 mTrayMenu->addAction(act);
403 mTrayMenu->addSeparator();
404 QAction *config = new QAction(tr("Configure"), this);
405 config->setData("configure");
406 mTrayMenu->addAction(config);
408 mTrayMenu->addSeparator();
409 QAction *about_jrugr = new QAction(tr("About Jrugr"), this);
410 about_jrugr->setData("about_jrugr");
411 mTrayMenu->addAction(about_jrugr);
413 QAction *about_qt = new QAction(tr("About Qt"), this);
414 about_qt->setData("about_qt");
415 mTrayMenu->addAction(about_qt);
417 mTrayMenu->addSeparator();
418 QAction *jrugrExit = new QAction(tr("Exit"), this);
419 jrugrExit->setData("exit");
420 mTrayMenu->addAction(jrugrExit);
424 void Jrugr::buildIcon () {
425 if (!mTrayIcon) return;
426 mTrayIcon->setIcon(langIcon(mGroupInfo[mActiveGroup].sym, 32, 22, !jCfg->showFlag));
427 mTrayIcon->setToolTip(mGroupInfo[mActiveGroup].name);
428 if (mTrayMenu) mTrayIcon->setContextMenu(mTrayMenu);
429 mTrayIcon->show();
433 void Jrugr::trayClicked (QSystemTrayIcon::ActivationReason reason) {
434 switch (reason) {
435 case QSystemTrayIcon::Trigger: setNextGroup(); break;
436 case QSystemTrayIcon::DoubleClick: setNextGroup(); break;
437 case QSystemTrayIcon::MiddleClick: setPrevGroup(); break;
438 default: ;
443 // new layout activated; fix all necessary shit
444 void Jrugr::onGroupChanged (int index) {
445 qDebug() << "Jrugr::onGroupChanged: index:" << index;
446 mActiveGroup = index;
447 buildIcon();
449 if (mActiveWindow != None) {
450 WinInfo *wi = findWindowInfo(mActiveWindow);
452 if (!wi) {
453 qDebug() << "new window";
454 installFacehuggers();
455 wi = findWindowInfo(mActiveWindow);
458 if (wi) {
459 qDebug() << "fixing window layout";
460 wi->layout = index;
461 if (index < mGroupInfo.size()) X11Tools::setjprop(wi->w, "WIN_LAYOUT", mGroupInfo[index].sym);
462 if (jCfg->switching == APP_LAYOUT) {
463 wi = findAppInfo(mActiveWindow);
464 if (wi) {
465 qDebug() << "fixing app layout";
466 wi->layout = index;
467 if (index < mGroupInfo.size()) X11Tools::setjprop(wi->w, "APP_LAYOUT", mGroupInfo[index].sym);
468 } else {
469 qWarning() << "***APP SHIT!***";
472 } else {
473 qWarning() << "***WINDOW SHIT!***";
477 setDesktopLayout(X11Tools::activeDesktop(), mActiveGroup);
481 void Jrugr::setNextGroup () {
482 mXkb->setActiveGroup(mActiveGroup+1>=mGroupInfo.size()?0:mActiveGroup+1);
486 void Jrugr::setPrevGroup () {
487 mXkb->setActiveGroup(mActiveGroup-1<0?mGroupInfo.size()-1:mActiveGroup-1);
491 void Jrugr::windowDies (Window w) {
492 if (w != None) {
493 qDebug("**************************** FACEHUGGER PARENT DIES ****************************");
494 Window appW = None;
495 // remove window
497 QWIHashMutableIterator i(mKnownWindows);
498 while (i.hasNext()) {
499 WinInfo *wi = i.next().value();
501 if (wi->w == w) {
502 i.remove();
503 if (wi->w == wi->appWindow) {
504 if (appW == None) appW = wi->w;
505 else if (appW != wi->w) qWarning("*** WTF?! ***");
507 delete wi;
511 if (appW != None) {
512 // remove application
513 QWIHashMutableIterator i(mKnownApps);
514 while (i.hasNext()) {
515 WinInfo *wi = i.next().value();
517 if (wi->w == appW) {
518 i.remove();
519 delete wi;
527 void Jrugr::onChangeLayout (int index) {
528 qDebug() << "Jrugr::changeLayout:" << index;
529 mXkb->setActiveGroup(index);
533 void Jrugr::actionsActivate (QAction *action) {
534 QString cmd = action->data().toString();
536 qDebug() << "Jrugr::actionsActivate() command" << cmd;
537 if (cmd == "configure") {
538 configure();
539 } else if (cmd == "about_qt") {
540 aboutQt();
541 } else if (cmd == "about_jrugr") {
542 QMessageBox::about(0,
543 tr("About Jrugr"),
544 tr("<h2>Jrugr, the keyboard layout switcher</h2>"
545 "<b>Version</b>: %1<p>"
546 "Gui tool to configure XKB extentions of X server.<p>"
547 "(c) 2009-2011 Fedor Chelbarakh, Petr Vanek, Ketmar").arg(JRUGR_VERSION));
548 } else if (cmd == "exit") {
549 qDebug() << "Jrugr::actionsActivate() exit";
550 quit();
551 } else {
552 for (int f = mGroupInfo.size()-1; f >= 0; --f) {
553 if (cmd == mGroupInfo[f].name) {
554 emit changeLayout(f);
555 break;
562 #ifdef K8_MPLAYER_HACK
563 static bool isMPlayer (Window w) {
564 if (w != None) {
565 if (X11Tools::windowDesktop(w) == -1 && X11Tools::windowClass(w) == "xv") {
566 QString name = X11Tools::windowName(w).toLower();
567 if (name == "mplayer" || name == "mplayer2") return true;
570 return false;
574 static QX11WindowList getPossibleActives (Window mpw) {
575 QX11WindowList res, wl = X11Tools::topLevelWindowStack();
576 int desk = X11Tools::activeDesktop();
577 Window wine = None;
579 qDebug() << "looking for window to refocus...";
580 for (int f = 0; f < wl.size(); ++f) {
581 Window w = wl.at(f);
582 int wd = X11Tools::windowDesktop(w);
584 if (wd == desk) {
585 // skip 'special' windows
586 QStringList sl = X11Tools::windowStateNames(w);
587 if (sl.indexOf("_NET_WM_STATE_STICKY") < 0 &&
588 sl.indexOf("_NET_WM_STATE_HIDDEN") < 0 &&
589 sl.indexOf("_NET_WM_STATE_SHADED") < 0 &&
590 sl.indexOf("_NET_WM_STATE_SKIP_TASKBAR") < 0 &&
591 sl.indexOf("_NET_WM_STATE_ABOVE") < 0 &&
592 sl.indexOf("_NET_WM_STATE_BELOW") < 0) {
593 QString cls(X11Tools::windowClass(w));
594 if (cls == "xv") {
595 QString name(X11Tools::windowName(w).toLower());
596 if (name == "mplayer" || name == "mplayer2") continue;
598 if (wine == None && cls == "explorer.exe") {
599 wine = w;
600 qDebug() << " WINE:" << cls;
601 } else {
602 //FIXME: this will not work as expected!
603 if (f > 0 && wl.at(f-1) == mpw) {
604 res.prepend(w);
605 } else {
606 res << w;
608 qDebug() << " NORM:" << cls;
614 if (wine != None) res << wine;
616 return res;
620 bool Jrugr::deactivateMPlayer () {
621 qDebug() << "onActiveWindowChanged";
622 Window aw = X11Tools::activeWindow();
623 bool changeFocus = false;
625 if (aw != None) {
626 if (X11Tools::windowDesktop(aw) == -1 && X11Tools::windowClass(aw) == "xv") {
627 QString name = X11Tools::windowName(aw).toLower();
628 if (name == "mplayer" || name == "mplayer2") {
629 qDebug() << "MPlayer hack!";
630 changeFocus = true;
633 } else {
634 qDebug() << "Empty window hack!";
635 changeFocus = true;
638 if (changeFocus) {
639 // find previous window
640 Window pw = deskActiveWindow(mCurDesk);
641 int dsk = X11Tools::windowDesktop(pw);
642 if (pw == None || isMPlayer(pw) || (dsk != -1 && dsk != mCurDesk)) {
643 QX11WindowList wl = getPossibleActives(aw);
645 if (wl.size() > 0) pw = wl.at(wl.size()-1); else pw = None;
647 if (pw != None) {
648 qDebug() << "CHANGING FOCUS!" <<
649 "class:" << X11Tools::windowClass(pw) <<
650 "name:" << X11Tools::windowName(pw) <<
651 "pid:" << X11Tools::windowPID(pw);
653 X11Tools::setActiveWindow(pw);
654 return true;
657 return false;
661 void Jrugr::onMPFix () {
662 if (!deactivateMPlayer()) setDeskActiveWindow(mCurDesk, mActiveWindow);
664 #endif
667 void Jrugr::onActiveWindowChanged (Window w) {
668 qDebug() << "onActiveWindowChanged";
669 if (w == None) {
670 #ifdef K8_MPLAYER_HACK
671 if (mDeskJustChanged) {
672 //deactivateMPlayer();
673 if (mMplayerHack) {
674 mMPFix->start(MPLAYER_HACK_TIMEOUT);
676 mDeskJustChanged = false;
678 #else
679 setDeskActiveWindow(mCurDesk, w);
680 #endif
681 mActiveWindow = None;
682 qDebug() << "new active window: NONE";
683 return;
685 qDebug() << "new active window:" << (int)w << "desktop:" << X11Tools::windowDesktop(w);
686 dumpWinInfo("new active window:", w);
688 if (mDeskJustChanged) {
689 qDebug() << "*** mDeskJustChanged ***";
690 mDeskJustChanged = false;
691 #ifdef K8_MPLAYER_HACK
692 if (mMplayerHack && isMPlayer(w)) {
693 //mMPFix->start(MPLAYER_HACK_TIMEOUT);
694 if (deactivateMPlayer()) return;
696 #endif
699 #ifdef K8_MPLAYER_HACK
700 if (!mMplayerHack || !isMPlayer(w))
701 #endif
702 setDeskActiveWindow(mCurDesk, w);
704 WinInfo *wi = findWindowInfo(w), *aw;
705 if (!wi) {
706 qDebug() << "new window";
707 installFacehuggers();
708 wi = findWindowInfo(w);
710 if (wi) {
711 switch (jCfg->switching) {
712 case APP_LAYOUT:
713 if ((aw = findAppInfo(w)) != findAppInfo(mActiveWindow)) {
714 qDebug("application changed!");
715 if (aw) {
716 if (aw->layout != mActiveGroup) {
717 qDebug("enforcing layout %d", aw->layout);
718 emit changeLayout(aw->layout);
720 } else {
721 qWarning("*** APP SHIT! ***");
724 break;
725 case WIN_LAYOUT:
726 if (wi->layout != mActiveGroup) {
727 qDebug("enforcing layout %d", wi->layout);
728 emit changeLayout(wi->layout);
730 break;
731 default: break;
735 mActiveWindow = w;
739 void Jrugr::onClientListChanged () {
740 qDebug() << "onClientListChanged";
741 installFacehuggers();
745 void Jrugr::onActiveDesktopChanged (int desk) {
746 qDebug() << "onActiveDesktopChanged:" << desk;
747 mDeskJustChanged = true;
748 #ifdef K8_MPLAYER_HACK
749 //if (deactivateMPlayer()) mDeskJustChanged = false;
750 if (mMplayerHack) {
751 mMPFix->start(MPLAYER_HACK_TIMEOUT);
753 #endif
754 if (jCfg->switching == DESK_LAYOUT && mCurDesk != desk) {
755 int ll = desktopLayout(desk);
756 setDesktopLayout(desk, ll); // expand desktop list
757 if (ll != mActiveGroup) {
758 qDebug("enforce layout %d for desktop %d", ll, desk);
759 emit changeLayout(mDeskLangs.at(desk));
762 mCurDesk = desk;
766 bool Jrugr::x11EventFilter (XEvent *event) {
768 //qDebug() << "Jrugr::x11EventFilter:" << x11EventName(event);
769 switch (event->type) {
770 case DestroyNotify:
771 windowDies(event->xdestroywindow.window);
772 break;
773 case PropertyNotify:
774 if (event->xproperty.state == PropertyNewValue) {
775 if (atomActWin != None && event->xproperty.atom == atomActWin) {
776 //qDebug() << "emit: activeWindowChanged";
777 emit activeWindowChanged();
779 if (atomCurDesk != None && event->xproperty.atom == atomCurDesk) {
780 //qDebug() << "emit: activeDesktopChanged";
781 emit activeDesktopChanged();
783 if (atomClientList != None && event->xproperty.atom == atomClientList) {
784 qDebug() << "emit: clientListChanged";
785 emit clientListChanged();
788 //qDebug() << "PropertyNotify complete";
789 break;
790 default:
791 if (mXkb) mXkb->processEvent(event);
792 //return false;
793 break;
795 return false; // normal dispatching