fixed linker bug
[jrugr.git] / src / jrugr.cpp
bloba17f4f751de7524b729f319502fa89dd164e6199
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 bool Jrugr::isKnownWindow (Window w) const {
211 return mKnownWindows.contains(w);
215 bool Jrugr::isKnownApp (Window w) const {
216 return mKnownApps.contains(X11Tools::appWindow(w));
220 WinInfo *Jrugr::findWindowInfo (Window w) {
221 return mKnownWindows.value(w, 0);
225 // find application info for the given window
226 WinInfo *Jrugr::findAppInfo (Window w) {
227 return mKnownApps.value(X11Tools::appWindow(w), 0);
231 int Jrugr::desktopLayout (int desk) const {
232 if (desk < 0 || desk >= mDeskLangs.size()) return 0;
233 return mDeskLangs.at(desk);
237 void Jrugr::setDesktopLayout (int desk, int group) {
238 if (desk < 0 || desk > 42) return; // invalid desktop number
239 while (mDeskLangs.size() <= desk) mDeskLangs << 0;
240 mDeskLangs[desk] = group;
244 Window Jrugr::deskActiveWindow (int desk) {
245 if (desk < 0 || desk >= mDeskActiveWindows.size()) return None;
246 return mDeskActiveWindows.at(desk);
250 void Jrugr::setDeskActiveWindow (int desk, Window w) {
251 if (desk < 0 || desk > 42) return; // invalid desktop number
252 while (mDeskActiveWindows.size() <= desk) mDeskActiveWindows << None;
253 mDeskActiveWindows[desk] = w;
254 if (w != None) {
255 qDebug() << "DESK:" << desk <<
256 "class:" << X11Tools::windowClass(w) <<
257 "name:" << X11Tools::windowName(w);
258 } else {
259 qDebug() << "DESK:" << desk << "None";
264 void Jrugr::installFacehuggers () {
265 QX11WindowList wl = X11Tools::topLevelWindows();
266 QSet<WId> qtwl;
269 //QWidgetList twl = QApplication::allWidgets();
270 QWidgetList twl = QApplication::topLevelWidgets();
271 foreach (QWidget *wd, twl) {
272 WId w = wd->effectiveWinId();
273 if (w != None) qtwl << w;
277 for (int f = 0; f < wl.size(); ++f) {
278 if (wl[f] != None && !qtwl.contains(wl[f]) && !isKnownWindow(wl[f])) {
279 WinInfo *wi = new WinInfo;
281 wi->w = wl[f];
282 wi->appWindow = X11Tools::appWindow(wl[f]);
283 wi->layout = 0;
284 mKnownWindows[wl[f]] = wi;
285 makeFacehugger(wi->w);
287 if (wi->appWindow == wi->w && !isKnownApp(wi->w)) {
288 WinInfo *w2 = new WinInfo;
290 w2->appWindow = w2->w = wi->w;
291 w2->layout = wi->layout;
292 mKnownApps[w2->w] = w2;
299 void Jrugr::doActiveWindowChanged () {
300 //qDebug() << "doActiveWindowChanged";
301 onActiveWindowChanged(X11Tools::activeWindow());
305 void Jrugr::doActiveDesktopChanged () {
306 //qDebug() << "doActiveDesktopChanged";
307 onActiveDesktopChanged(X11Tools::activeDesktop());
311 void Jrugr::onLayoutChanged () {
312 qDebug()<<"Jrugr::onLayoutChanged : reconfig";
313 reconfigure();
314 qDebug()<<"Jrugr::onLayoutChanged : done";
318 QIcon Jrugr::langIcon (const QString &lsym, int wdt, int hgt, bool noFlag) {
319 if (!noFlag) {
320 QString path = mLangThemePath+fixLayoutName(lsym, jCfg->useSU);
321 QString SVGfile = path+".svg";
323 if (QFile::exists(SVGfile)) {
324 QSvgRenderer flagSVG(SVGfile);
325 if (flagSVG.isValid()) {
326 QPixmap pix(wdt, hgt);
327 QPainter painter;
328 painter.begin(&pix);
329 flagSVG.render(&painter, QRectF(0, 0, wdt, hgt));
330 painter.end();
331 return QIcon(pix);
335 QString PNGfile = path+".png";
336 if (QFile::exists(PNGfile)) {
337 return QIcon(PNGfile);
342 qDebug() << ":::" << lsym;
343 QFont font("Helvetica [Cronyx]", 15); //FIXME: should be configurable
344 //QFont font("Tahoma", 15);
345 font.setBold(true);
346 font.setLetterSpacing(QFont::PercentageSpacing, 120);
347 QPixmap pix(lsym.length()*20, 26);
348 QPainter painter;
349 painter.begin(&pix);
350 painter.setFont(font);
351 painter.fillRect(pix.rect(), Qt::darkGray);
352 painter.setPen(Qt::white);
353 painter.drawText(pix.rect(), Qt::AlignVCenter|Qt::AlignCenter, lsym);
354 painter.end();
355 return QIcon(pix);
360 void Jrugr::createMenu () {
361 if (!mTrayMenu) {
362 mTrayMenu = new QMenu();
363 connect(mTrayMenu, SIGNAL(triggered(QAction *)), SLOT(actionsActivate(QAction *)));
364 } else {
365 mTrayMenu->clear();
368 for (int index = 0; index < mGroupInfo.size(); ++index) {
369 QString lname = mGroupInfo[index].name, lsym = mGroupInfo[index].sym;
371 QAction *act = new QAction(lname, this);
372 act->setIcon(langIcon(lsym));
373 act->setData(lname);
374 mTrayMenu->addAction(act);
377 mTrayMenu->addSeparator();
378 QAction *config = new QAction(tr("Configure"), this);
379 config->setData("configure");
380 mTrayMenu->addAction(config);
382 mTrayMenu->addSeparator();
383 QAction *about_jrugr = new QAction(tr("About Jrugr"), this);
384 about_jrugr->setData("about_jrugr");
385 mTrayMenu->addAction(about_jrugr);
387 QAction *about_qt = new QAction(tr("About Qt"), this);
388 about_qt->setData("about_qt");
389 mTrayMenu->addAction(about_qt);
391 mTrayMenu->addSeparator();
392 QAction *jrugrExit = new QAction(tr("Exit"), this);
393 jrugrExit->setData("exit");
394 mTrayMenu->addAction(jrugrExit);
398 void Jrugr::buildIcon () {
399 if (!mTrayIcon) return;
400 mTrayIcon->setIcon(langIcon(mGroupInfo[mActiveGroup].sym, 32, 22, !jCfg->showFlag));
401 mTrayIcon->setToolTip(mGroupInfo[mActiveGroup].name);
402 if (mTrayMenu) mTrayIcon->setContextMenu(mTrayMenu);
403 mTrayIcon->show();
407 void Jrugr::trayClicked (QSystemTrayIcon::ActivationReason reason) {
408 switch (reason) {
409 case QSystemTrayIcon::Trigger: setNextGroup(); break;
410 case QSystemTrayIcon::DoubleClick: setNextGroup(); break;
411 case QSystemTrayIcon::MiddleClick: setPrevGroup(); break;
412 default: ;
417 // new layout activated; fix all necessary shit
418 void Jrugr::onGroupChanged (int index) {
419 qDebug() << "Jrugr::onGroupChanged: index:" << index;
420 mActiveGroup = index;
421 buildIcon();
423 if (mActiveWindow != None) {
424 WinInfo *wi = findWindowInfo(mActiveWindow);
426 if (!wi) {
427 qDebug() << "new window";
428 installFacehuggers();
429 wi = findWindowInfo(mActiveWindow);
432 if (wi) {
433 qDebug() << "fixing window layout";
434 wi->layout = index;
435 if (jCfg->switching == APP_LAYOUT) {
436 wi = findAppInfo(mActiveWindow);
437 if (wi) {
438 qDebug() << "fixing app layout";
439 wi->layout = index;
440 } else {
441 qWarning() << "***APP SHIT!***";
444 } else {
445 qWarning() << "***WINDOW SHIT!***";
449 setDesktopLayout(X11Tools::activeDesktop(), mActiveGroup);
453 void Jrugr::setNextGroup () {
454 mXkb->setActiveGroup(mActiveGroup+1>=mGroupInfo.size()?0:mActiveGroup+1);
458 void Jrugr::setPrevGroup () {
459 mXkb->setActiveGroup(mActiveGroup-1<0?mGroupInfo.size()-1:mActiveGroup-1);
463 void Jrugr::windowDies (Window w) {
464 if (w != None) {
465 qDebug("**************************** FACEHUGGER PARENT DIES ****************************");
466 Window appW = None;
467 // remove window
469 QWIHashMutableIterator i(mKnownWindows);
470 while (i.hasNext()) {
471 WinInfo *wi = i.next().value();
473 if (wi->w == w) {
474 i.remove();
475 if (wi->w == wi->appWindow) {
476 if (appW == None) appW = wi->w;
477 else if (appW != wi->w) qWarning("*** WTF?! ***");
479 delete wi;
483 if (appW != None) {
484 // remove application
485 QWIHashMutableIterator i(mKnownApps);
486 while (i.hasNext()) {
487 WinInfo *wi = i.next().value();
489 if (wi->w == appW) {
490 i.remove();
491 delete wi;
499 void Jrugr::onChangeLayout (int index) {
500 qDebug() << "Jrugr::changeLayout:" << index;
501 mXkb->setActiveGroup(index);
505 void Jrugr::actionsActivate (QAction *action) {
506 QString cmd = action->data().toString();
508 qDebug() << "Jrugr::actionsActivate() command" << cmd;
509 if (cmd == "configure") {
510 configure();
511 } else if (cmd == "about_qt") {
512 aboutQt();
513 } else if (cmd == "about_jrugr") {
514 QMessageBox::about(0,
515 tr("About Jrugr"),
516 tr("<h2>Jrugr, the keyboard layout switcher</h2>"
517 "<b>Version</b>: %1<p>"
518 "Gui tool to configure XKB extentions of X server.<p>"
519 "(c) 2009-2011 Fedor Chelbarakh, Petr Vanek, Ketmar").arg(JRUGR_VERSION));
520 } else if (cmd == "exit") {
521 qDebug() << "Jrugr::actionsActivate() exit";
522 quit();
523 } else {
524 for (int f = mGroupInfo.size()-1; f >= 0; --f) {
525 if (cmd == mGroupInfo[f].name) {
526 emit changeLayout(f);
527 break;
534 #ifdef K8_MPLAYER_HACK
535 static bool isMPlayer (Window w) {
536 if (w != None) {
537 if (X11Tools::windowDesktop(w) == -1 && X11Tools::windowClass(w) == "xv") {
538 QString name = X11Tools::windowName(w).toLower();
539 if (name == "mplayer" || name == "mplayer2") return true;
542 return false;
546 static QX11WindowList getPossibleActives (Window mpw) {
547 QX11WindowList res, wl = X11Tools::topLevelWindowStack();
548 int desk = X11Tools::activeDesktop();
549 Window wine = None;
551 qDebug() << "looking for window to refocus...";
552 for (int f = 0; f < wl.size(); ++f) {
553 Window w = wl.at(f);
554 int wd = X11Tools::windowDesktop(w);
556 if (wd == desk) {
557 // skip 'special' windows
558 QStringList sl = X11Tools::windowStateNames(w);
559 if (sl.indexOf("_NET_WM_STATE_STICKY") < 0 &&
560 sl.indexOf("_NET_WM_STATE_HIDDEN") < 0 &&
561 sl.indexOf("_NET_WM_STATE_SHADED") < 0 &&
562 sl.indexOf("_NET_WM_STATE_SKIP_TASKBAR") < 0 &&
563 sl.indexOf("_NET_WM_STATE_ABOVE") < 0 &&
564 sl.indexOf("_NET_WM_STATE_BELOW") < 0) {
565 QString cls(X11Tools::windowClass(w));
566 if (cls == "xv") {
567 QString name(X11Tools::windowName(w).toLower());
568 if (name == "mplayer" || name == "mplayer2") continue;
570 if (wine == None && cls == "explorer.exe") {
571 wine = w;
572 qDebug() << " WINE:" << cls;
573 } else {
574 //FIXME: this will not work as expected!
575 if (f > 0 && wl.at(f-1) == mpw) {
576 res.prepend(w);
577 } else {
578 res << w;
580 qDebug() << " NORM:" << cls;
586 if (wine != None) res << wine;
588 return res;
592 bool Jrugr::deactivateMPlayer () {
593 qDebug() << "onActiveWindowChanged";
594 Window aw = X11Tools::activeWindow();
595 bool changeFocus = false;
597 if (aw != None) {
598 if (X11Tools::windowDesktop(aw) == -1 && X11Tools::windowClass(aw) == "xv") {
599 QString name = X11Tools::windowName(aw).toLower();
600 if (name == "mplayer" || name == "mplayer2") {
601 qDebug() << "MPlayer hack!";
602 changeFocus = true;
605 } else {
606 qDebug() << "Empty window hack!";
607 changeFocus = true;
610 if (changeFocus) {
611 // find previous window
612 Window pw = deskActiveWindow(mCurDesk);
613 int dsk = X11Tools::windowDesktop(pw);
614 if (pw == None || isMPlayer(pw) || (dsk != -1 && dsk != mCurDesk)) {
615 QX11WindowList wl = getPossibleActives(aw);
617 if (wl.size() > 0) pw = wl.at(wl.size()-1); else pw = None;
619 if (pw != None) {
620 qDebug() << "CHANGING FOCUS!" <<
621 "class:" << X11Tools::windowClass(pw) <<
622 "name:" << X11Tools::windowName(pw) <<
623 "pid:" << X11Tools::windowPID(pw);
625 X11Tools::setActiveWindow(pw);
626 return true;
629 return false;
633 void Jrugr::onMPFix () {
634 if (!deactivateMPlayer()) setDeskActiveWindow(mCurDesk, mActiveWindow);
636 #endif
639 void Jrugr::onActiveWindowChanged (Window w) {
640 qDebug() << "onActiveWindowChanged";
641 if (w == None) {
642 #ifdef K8_MPLAYER_HACK
643 if (mDeskJustChanged) {
644 //deactivateMPlayer();
645 if (mMplayerHack) {
646 mMPFix->start(MPLAYER_HACK_TIMEOUT);
648 mDeskJustChanged = false;
650 #else
651 setDeskActiveWindow(mCurDesk, w);
652 #endif
653 mActiveWindow = None;
654 qDebug() << "new active window: NONE";
655 return;
657 qDebug() << "new active window:" << (int)w << "desktop:" << X11Tools::windowDesktop(w);
658 dumpWinInfo("new active window:", w);
660 if (mDeskJustChanged) {
661 qDebug() << "*** mDeskJustChanged ***";
662 mDeskJustChanged = false;
663 #ifdef K8_MPLAYER_HACK
664 if (mMplayerHack && isMPlayer(w)) {
665 //mMPFix->start(MPLAYER_HACK_TIMEOUT);
666 if (deactivateMPlayer()) return;
668 #endif
671 #ifdef K8_MPLAYER_HACK
672 if (!mMplayerHack || !isMPlayer(w))
673 #endif
674 setDeskActiveWindow(mCurDesk, w);
676 WinInfo *wi = findWindowInfo(w), *aw;
677 if (!wi) {
678 qDebug() << "new window";
679 installFacehuggers();
680 wi = findWindowInfo(w);
682 if (wi) {
683 switch (jCfg->switching) {
684 case APP_LAYOUT:
685 if ((aw = findAppInfo(w)) != findAppInfo(mActiveWindow)) {
686 qDebug("application changed!");
687 if (aw) {
688 if (aw->layout != mActiveGroup) {
689 qDebug("enforcing layout %d", aw->layout);
690 emit changeLayout(aw->layout);
692 } else {
693 qWarning("*** APP SHIT! ***");
696 break;
697 case WIN_LAYOUT:
698 if (wi->layout != mActiveGroup) {
699 qDebug("enforcing layout %d", wi->layout);
700 emit changeLayout(wi->layout);
702 break;
703 default: break;
707 mActiveWindow = w;
711 void Jrugr::onClientListChanged () {
712 qDebug() << "onClientListChanged";
713 installFacehuggers();
717 void Jrugr::onActiveDesktopChanged (int desk) {
718 qDebug() << "onActiveDesktopChanged:" << desk;
719 mDeskJustChanged = true;
720 #ifdef K8_MPLAYER_HACK
721 //if (deactivateMPlayer()) mDeskJustChanged = false;
722 if (mMplayerHack) {
723 mMPFix->start(MPLAYER_HACK_TIMEOUT);
725 #endif
726 if (jCfg->switching == DESK_LAYOUT && mCurDesk != desk) {
727 int ll = desktopLayout(desk);
728 setDesktopLayout(desk, ll); // expand desktop list
729 if (ll != mActiveGroup) {
730 qDebug("enforce layout %d for desktop %d", ll, desk);
731 emit changeLayout(mDeskLangs.at(desk));
734 mCurDesk = desk;
738 bool Jrugr::x11EventFilter (XEvent *event) {
740 //qDebug() << "Jrugr::x11EventFilter:" << x11EventName(event);
741 switch (event->type) {
742 case DestroyNotify:
743 windowDies(event->xdestroywindow.window);
744 break;
745 case PropertyNotify:
746 if (event->xproperty.state == PropertyNewValue) {
747 if (atomActWin != None && event->xproperty.atom == atomActWin) {
748 //qDebug() << "emit: activeWindowChanged";
749 emit activeWindowChanged();
751 if (atomCurDesk != None && event->xproperty.atom == atomCurDesk) {
752 //qDebug() << "emit: activeDesktopChanged";
753 emit activeDesktopChanged();
755 if (atomClientList != None && event->xproperty.atom == atomClientList) {
756 qDebug() << "emit: clientListChanged";
757 emit clientListChanged();
760 //qDebug() << "PropertyNotify complete";
761 break;
762 default:
763 mXkb->processEvent(event);
764 //return false;
765 break;
767 return false; // normal dispatching