more mpv hack fixes
[jrugr.git] / src / jrugr.cpp
blob4dd305cb9405f7b13e3894be87a669da2dcf2f99
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 inline bool isMPlayer (const QString &name) {
16 return (
17 name.startsWith("mplayer", Qt::CaseInsensitive) ||
18 name.startsWith("mplayer2", Qt::CaseInsensitive) ||
19 name.startsWith("mpv", Qt::CaseInsensitive)
24 static inline bool isMPlayerClass (const QString &name) {
25 return (name == "xv" || name == "gl" || name == "vdpau");
29 ////////////////////////////////////////////////////////////////////////////////
30 static bool makeFacehugger (Window w) {
31 //WARNING! this WILL NOT work as expected on our own windows!
32 return XSelectInput(QX11Info::display(), w, /*SubstructureNotifyMask |*/ StructureNotifyMask) == Success;
36 static void dumpWinInfo (const char *msg, Window w) {
37 Window pw;
39 if (w == None) return;
40 pw = X11Tools::windowTransientFor(w);
41 qDebug() << msg << (int)(w) <<
42 "class:" << X11Tools::windowClass(w) <<
43 "name:" << X11Tools::windowName(w) <<
44 "pid:" << X11Tools::windowPID(w) <<
45 "transientfor:" << pw;
46 //dumpWinInfo(" parent (tr)", pw);
50 ////////////////////////////////////////////////////////////////////////////////
51 Jrugr::Jrugr (int &argc, char **argv) :
52 QApplication(argc, argv),
54 mActiveGroup(0),
55 mXkb(0),
56 mTrayIcon(0),
57 mTrayMenu(0),
58 jCfg(0),
59 mDeskJustChanged(false)
61 if (atomActWin == None) atomActWin = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True);
62 if (atomClientList == None) atomClientList = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", True);
63 if (atomCurDesk == None) atomCurDesk = XInternAtom(QX11Info::display(), "_NET_CURRENT_DESKTOP", True);
64 // mandatory to keep it running after closing about dialogs...
65 setQuitOnLastWindowClosed(false);
66 setWindowIcon(QIcon(":/about/jrugr.png"));
68 mCfgFileName = QDir::homePath()+"/.config/jrugr.cfg";
72 Jrugr::~Jrugr () {
73 delete mXkb;
74 delete mTrayMenu;
75 delete jCfg;
76 //! \warning the trayIcon *has* to be deleted here to prevent XFreeColormap() free corruption.
77 delete mTrayIcon;
81 bool Jrugr::firstStart () {
82 if (!QFile::exists(mCfgFileName)) {
83 QString themePath;
85 qDebug() << " Jrugr:Config file not found in:" << mCfgFileName;
86 QSettings jrugr(mCfgFileName, QSettings::IniFormat);
87 QDir themeDir("/usr/share/jrugr/theme/default");
88 if (themeDir.exists()) themePath = themeDir.path();
89 else themePath = QCoreApplication::applicationDirPath()+"/theme/default";;
90 jrugr.beginGroup("Style");
91 mLangThemePath = themePath;
92 jrugr.setValue("path", mLangThemePath);
93 jrugr.endGroup(); //Style
94 return true;
96 return false;
100 void Jrugr::startup () {
101 if (firstStart()) configure();
104 QSettings jrugr(mCfgFileName, QSettings::IniFormat, this);
105 jrugr.beginGroup("Style");
106 mLangThemePath = jrugr.value("path").toString()+"/language/";
107 jrugr.endGroup(); //Style
109 jCfg = JrugrCfg::load(mCfgFileName);
110 if (!jCfg) abort();
111 if (jCfg->workMode == USE_XKB) configureXkb();
112 mMplayerHack = jCfg->mplayerHack;
114 mXkb = new XKeyboard();
115 mXkb->groupInfo(mGroupInfo);
117 connect(mXkb, SIGNAL(groupChanged(int)), this, SLOT(onGroupChanged(int)), Qt::QueuedConnection);
118 connect(mXkb, SIGNAL(layoutChanged()), this, SLOT(onLayoutChanged()), Qt::QueuedConnection);
119 connect(this, SIGNAL(changeLayout(int)), this, SLOT(onChangeLayout(int)), Qt::QueuedConnection);
121 connect(this, SIGNAL(activeWindowChanged()), this, SLOT(doActiveWindowChanged()), Qt::QueuedConnection);
122 connect(this, SIGNAL(activeDesktopChanged()), this, SLOT(doActiveDesktopChanged()), Qt::QueuedConnection);
123 connect(this, SIGNAL(clientListChanged()), this, SLOT(onClientListChanged()), Qt::QueuedConnection);
125 #ifdef K8_MPLAYER_HACK
126 mMPFix = new QTimer(this);
127 mMPFix->setSingleShot(true);
128 connect(mMPFix, SIGNAL(timeout()), this, SLOT(onMPFix()), Qt::QueuedConnection);
129 #endif
133 void Jrugr::initialize () {
134 mXkb->groupInfo(mGroupInfo);
136 mMplayerHack = jCfg->mplayerHack;
137 mActiveGroup = mXkb->activeGroup();
138 mActiveWindow = X11Tools::activeWindow();
139 mCurDesk = X11Tools::activeDesktop();
140 setDeskActiveWindow(mCurDesk, X11Tools::activeWindow());
142 mTrayIcon = new QSystemTrayIcon(this);
143 connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClicked(QSystemTrayIcon::ActivationReason)));
145 createMenu();
146 buildIcon();
148 installFacehuggers();
152 void Jrugr::reconfigure () {
153 JrugrCfg *newConf = JrugrCfg::load(mCfgFileName);
155 if (newConf) {
156 QXkbLayoutList nl;
158 mXkb->groupInfo(nl);
159 bool diffGI = nl.size() != mGroupInfo.size();
161 if (!diffGI) {
162 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; }
165 if (diffGI || newConf->layouts != jCfg->layouts || newConf->showFlag != jCfg->showFlag ||
166 newConf->workMode != jCfg->workMode || newConf->switching != jCfg->switching ||
167 mMplayerHack != newConf->mplayerHack) {
168 delete jCfg;
169 jCfg = newConf;
170 mMplayerHack = jCfg->mplayerHack;
171 mGroupInfo = nl;
172 createMenu();
173 buildIcon();
174 } else {
175 delete newConf;
181 int Jrugr::setKeyLayout (QString keyConf) {
182 qDebug() << "Jrugr::setKeyLayout:" << keyConf;
183 QStringList argument = keyConf.split(" ");
184 qDebug() << " Jrugr:setxkbmap argumetns:" << argument;
185 int result = QProcess::execute("setxkbmap", argument);
186 qDebug() << " Jrugr:setxkbmap result:" << result;
187 return result;
191 void Jrugr::configureXkb () {
192 QString layout, variant, option;
193 QString model = jCfg->model;
195 for (int f = 0; f < jCfg->layouts.count(); ++f) {
196 layout += jCfg->layouts[f].layout;
197 variant += jCfg->layouts[f].variant;
198 if (f < jCfg->layouts.count()-1) { layout += ','; variant += ','; }
200 option = jCfg->options.join(",");
201 qDebug() << "Set layout:" << layout;
202 if (!(model.isEmpty() || model.isNull()) && !(layout.isEmpty() || layout.isNull())) {
203 QString args = "-model "+model+" -layout "+layout;
204 QString tmp = variant;
205 if (!variant.isNull() && !variant.isEmpty() && !tmp.remove(",").isEmpty()) args +=" -variant "+variant;
206 if (!option.isNull() && !option.isEmpty()) args +=" -option "+option;
207 qDebug() << " Jrugr:XKB args " << args;
208 if (setKeyLayout(args) == QProcess::CrashExit) {
209 qDebug() << " Jrugr:XKB isn`t set";
210 qDebug() << " Jrugr:------------------------------";
211 return;
213 qDebug() << " Jrugr:XKB set";
218 void Jrugr::configure () {
219 JrugrConfigForm *mCfgForm = new JrugrConfigForm(mCfgFileName);
220 connect(mCfgForm, SIGNAL(saveConfig()), SLOT(reconfigure()));
221 mCfgForm->exec(); // the form will die on closing
225 int Jrugr::layIndex (Window w, const QString &propname, bool unknownIsZero) const {
226 QString alay(X11Tools::getjprop(w, propname.toUtf8().constData()));
228 if (alay.size() > 0) {
229 int idx = XKeyboard::findBySym(mGroupInfo, alay);
231 qDebug() << "Win:" << w << "alay:" << alay << "idx:" << idx;
232 return idx;
234 return unknownIsZero ? 0 : -1;
238 bool Jrugr::isKnownWindow (Window w) const {
239 return mKnownWindows.contains(w);
243 bool Jrugr::isKnownApp (Window w) const {
244 return mKnownApps.contains(X11Tools::appWindow(w));
248 WinInfo *Jrugr::findWindowInfo (Window w) {
249 return mKnownWindows.value(w, 0);
253 // find application info for the given window
254 WinInfo *Jrugr::findAppInfo (Window w) {
255 return mKnownApps.value(X11Tools::appWindow(w), 0);
259 int Jrugr::desktopLayout (int desk) const {
260 if (desk < 0 || desk >= mDeskLangs.size()) return 0;
261 return mDeskLangs.at(desk);
265 void Jrugr::setDesktopLayout (int desk, int group) {
266 if (desk >= 0 && group < mGroupInfo.size()) {
267 X11Tools::setjprop(None, QString("DESK%1_LAYOUT").arg(desk), mGroupInfo[group].sym);
269 if (desk < 0 || desk > 42) return; // invalid desktop number
270 while (mDeskLangs.size() <= desk) {
271 QString ln(QString("DESK%1_LAYOUT").arg(mDeskLangs.size()));
272 int idx = layIndex(None, ln.toLatin1().constData(), true);
274 //qDebug() << "desk:" << mDeskLangs.size() << "layidx:" << idx;
275 if (group < mGroupInfo.size()) X11Tools::setjprop(None, ln, mGroupInfo[group].sym);
276 mDeskLangs << idx;
278 mDeskLangs[desk] = group;
282 Window Jrugr::deskActiveWindow (int desk) {
283 if (desk < 0 || desk >= mDeskActiveWindows.size()) return None;
284 return mDeskActiveWindows.at(desk);
288 void Jrugr::setDeskActiveWindow (int desk, Window w) {
289 if (desk < 0 || desk > 42) return; // invalid desktop number
290 while (mDeskActiveWindows.size() <= desk) mDeskActiveWindows << None;
291 mDeskActiveWindows[desk] = w;
292 if (w != None) {
293 qDebug() << "DESK:" << desk <<
294 "class:" << X11Tools::windowClass(w) <<
295 "name:" << X11Tools::windowName(w);
296 } else {
297 qDebug() << "DESK:" << desk << "None";
302 void Jrugr::installFacehuggers () {
303 QX11WindowList wl = X11Tools::topLevelWindows();
304 QSet<WId> qtwl;
307 //QWidgetList twl = QApplication::allWidgets();
308 QWidgetList twl = QApplication::topLevelWidgets();
309 foreach (QWidget *wd, twl) {
310 WId w = wd->effectiveWinId();
311 if (w != None) qtwl << w;
315 for (int f = 0; f < wl.size(); ++f) {
316 if (wl[f] != None && !qtwl.contains(wl[f]) && !isKnownWindow(wl[f])) {
317 WinInfo *wi = new WinInfo;
319 wi->w = wl[f];
320 wi->appWindow = X11Tools::appWindow(wl[f]);
321 wi->layout = layIndex(wi->w, "WIN_LAYOUT", true);
322 if (wi->layout < mGroupInfo.size()) X11Tools::setjprop(wi->w, "WIN_LAYOUT", mGroupInfo[wi->layout].sym);
323 mKnownWindows[wl[f]] = wi;
324 makeFacehugger(wi->w);
326 if (wi->appWindow == wi->w && !isKnownApp(wi->w)) {
327 WinInfo *w2 = new WinInfo;
329 w2->appWindow = w2->w = wi->w;
330 w2->layout = layIndex(w2->w, "APP_LAYOUT", false);
331 if (w2->layout < 0) w2->layout = wi->layout;
332 if (w2->layout < mGroupInfo.size()) X11Tools::setjprop(w2->w, "APP_LAYOUT", mGroupInfo[w2->layout].sym);
333 mKnownApps[w2->w] = w2;
340 void Jrugr::doActiveWindowChanged () {
341 //qDebug() << "doActiveWindowChanged";
342 onActiveWindowChanged(X11Tools::activeWindow());
346 void Jrugr::doActiveDesktopChanged () {
347 //qDebug() << "doActiveDesktopChanged";
348 onActiveDesktopChanged(X11Tools::activeDesktop());
352 void Jrugr::onLayoutChanged () {
353 qDebug()<<"Jrugr::onLayoutChanged : reconfig";
354 reconfigure();
355 qDebug()<<"Jrugr::onLayoutChanged : done";
359 QIcon Jrugr::langIcon (const QString &lsym, int wdt, int hgt, bool noFlag) {
360 if (!noFlag) {
361 QString path = mLangThemePath+fixLayoutName(lsym, jCfg->useSU);
362 QString SVGfile = path+".svg";
364 if (QFile::exists(SVGfile)) {
365 QSvgRenderer flagSVG(SVGfile);
366 if (flagSVG.isValid()) {
367 QPixmap pix(wdt, hgt);
368 QPainter painter;
369 painter.begin(&pix);
370 flagSVG.render(&painter, QRectF(0, 0, wdt, hgt));
371 painter.end();
372 return QIcon(pix);
376 QString PNGfile = path+".png";
377 if (QFile::exists(PNGfile)) {
378 return QIcon(PNGfile);
383 qDebug() << ":::" << lsym;
384 QFont font("Helvetica [Cronyx]", 15); //FIXME: should be configurable
385 //QFont font("Tahoma", 15);
386 font.setBold(true);
387 font.setLetterSpacing(QFont::PercentageSpacing, 120);
388 QPixmap pix(lsym.length()*20, 26);
389 QPainter painter;
390 painter.begin(&pix);
391 painter.setFont(font);
392 painter.fillRect(pix.rect(), Qt::darkGray);
393 painter.setPen(Qt::white);
394 painter.drawText(pix.rect(), Qt::AlignVCenter|Qt::AlignCenter, lsym);
395 painter.end();
396 return QIcon(pix);
401 void Jrugr::createMenu () {
402 if (!mTrayMenu) {
403 mTrayMenu = new QMenu();
404 connect(mTrayMenu, SIGNAL(triggered(QAction *)), SLOT(actionsActivate(QAction *)));
405 } else {
406 mTrayMenu->clear();
409 for (int index = 0; index < mGroupInfo.size(); ++index) {
410 QString lname = mGroupInfo[index].name, lsym = mGroupInfo[index].sym;
412 QAction *act = new QAction(lname, this);
413 act->setIcon(langIcon(lsym));
414 act->setData(lname);
415 mTrayMenu->addAction(act);
418 mTrayMenu->addSeparator();
419 QAction *config = new QAction(tr("Configure"), this);
420 config->setData("configure");
421 mTrayMenu->addAction(config);
423 mTrayMenu->addSeparator();
424 QAction *about_jrugr = new QAction(tr("About Jrugr"), this);
425 about_jrugr->setData("about_jrugr");
426 mTrayMenu->addAction(about_jrugr);
428 QAction *about_qt = new QAction(tr("About Qt"), this);
429 about_qt->setData("about_qt");
430 mTrayMenu->addAction(about_qt);
432 mTrayMenu->addSeparator();
433 QAction *jrugrExit = new QAction(tr("Exit"), this);
434 jrugrExit->setData("exit");
435 mTrayMenu->addAction(jrugrExit);
439 void Jrugr::buildIcon () {
440 if (!mTrayIcon) return;
441 mTrayIcon->setIcon(langIcon(mGroupInfo[mActiveGroup].sym, 32, 22, !jCfg->showFlag));
442 mTrayIcon->setToolTip(mGroupInfo[mActiveGroup].name);
443 if (mTrayMenu) mTrayIcon->setContextMenu(mTrayMenu);
444 mTrayIcon->show();
448 void Jrugr::trayClicked (QSystemTrayIcon::ActivationReason reason) {
449 switch (reason) {
450 case QSystemTrayIcon::Trigger: setNextGroup(); break;
451 case QSystemTrayIcon::DoubleClick: setNextGroup(); break;
452 case QSystemTrayIcon::MiddleClick: setPrevGroup(); break;
453 default: ;
458 // new layout activated; fix all necessary shit
459 void Jrugr::onGroupChanged (int index) {
460 qDebug() << "Jrugr::onGroupChanged: index:" << index;
461 mActiveGroup = index;
462 buildIcon();
464 if (mActiveWindow != None) {
465 WinInfo *wi = findWindowInfo(mActiveWindow);
467 if (!wi) {
468 qDebug() << "new window";
469 installFacehuggers();
470 wi = findWindowInfo(mActiveWindow);
473 if (wi) {
474 qDebug() << "fixing window layout";
475 wi->layout = index;
476 if (index < mGroupInfo.size()) X11Tools::setjprop(wi->w, "WIN_LAYOUT", mGroupInfo[index].sym);
477 if (jCfg->switching == APP_LAYOUT) {
478 wi = findAppInfo(mActiveWindow);
479 if (wi) {
480 qDebug() << "fixing app layout";
481 wi->layout = index;
482 if (index < mGroupInfo.size()) X11Tools::setjprop(wi->w, "APP_LAYOUT", mGroupInfo[index].sym);
483 } else {
484 qWarning() << "***APP SHIT!***";
487 } else {
488 qWarning() << "***WINDOW SHIT!***";
492 setDesktopLayout(X11Tools::activeDesktop(), mActiveGroup);
496 void Jrugr::setNextGroup () {
497 mXkb->setActiveGroup(mActiveGroup+1>=mGroupInfo.size()?0:mActiveGroup+1);
501 void Jrugr::setPrevGroup () {
502 mXkb->setActiveGroup(mActiveGroup-1<0?mGroupInfo.size()-1:mActiveGroup-1);
506 void Jrugr::windowDies (Window w) {
507 if (w != None) {
508 qDebug("**************************** FACEHUGGER PARENT DIES ****************************");
509 Window appW = None;
510 // remove window
512 QWIHashMutableIterator i(mKnownWindows);
513 while (i.hasNext()) {
514 WinInfo *wi = i.next().value();
516 if (wi->w == w) {
517 i.remove();
518 if (wi->w == wi->appWindow) {
519 if (appW == None) appW = wi->w;
520 else if (appW != wi->w) qWarning("*** WTF?! ***");
522 delete wi;
526 if (appW != None) {
527 // remove application
528 QWIHashMutableIterator i(mKnownApps);
529 while (i.hasNext()) {
530 WinInfo *wi = i.next().value();
532 if (wi->w == appW) {
533 i.remove();
534 delete wi;
542 void Jrugr::onChangeLayout (int index) {
543 qDebug() << "Jrugr::changeLayout:" << index;
544 mXkb->setActiveGroup(index);
548 void Jrugr::actionsActivate (QAction *action) {
549 QString cmd = action->data().toString();
551 qDebug() << "Jrugr::actionsActivate() command" << cmd;
552 if (cmd == "configure") {
553 configure();
554 } else if (cmd == "about_qt") {
555 aboutQt();
556 } else if (cmd == "about_jrugr") {
557 QMessageBox::about(0,
558 tr("About Jrugr"),
559 tr("<h2>Jrugr, the keyboard layout switcher</h2>"
560 "<b>Version</b>: %1<p>"
561 "Gui tool to configure XKB extentions of X server.<p>"
562 "(c) 2009-2011 Fedor Chelbarakh, Petr Vanek, Ketmar").arg(JRUGR_VERSION));
563 } else if (cmd == "exit") {
564 qDebug() << "Jrugr::actionsActivate() exit";
565 quit();
566 } else {
567 for (int f = mGroupInfo.size()-1; f >= 0; --f) {
568 if (cmd == mGroupInfo[f].name) {
569 emit changeLayout(f);
570 break;
577 #ifdef K8_MPLAYER_HACK
578 static bool isMPlayer (Window w) {
579 if (w != None) {
580 if (X11Tools::windowDesktop(w) == -1 && isMPlayerClass(X11Tools::windowClass(w))) {
581 QString name = X11Tools::windowName(w).toLower();
582 if (isMPlayer(name)) return true;
585 return false;
589 static QX11WindowList getPossibleActives (Window mpw) {
590 QX11WindowList res, wl = X11Tools::topLevelWindowStack();
591 int desk = X11Tools::activeDesktop();
592 Window wine = None;
594 qDebug() << "looking for window to refocus...";
595 for (int f = 0; f < wl.size(); ++f) {
596 Window w = wl.at(f);
597 int wd = X11Tools::windowDesktop(w);
599 if (wd == desk) {
600 // skip 'special' windows
601 QStringList sl = X11Tools::windowStateNames(w);
602 if (sl.indexOf("_NET_WM_STATE_STICKY") < 0 &&
603 sl.indexOf("_NET_WM_STATE_HIDDEN") < 0 &&
604 sl.indexOf("_NET_WM_STATE_SHADED") < 0 &&
605 sl.indexOf("_NET_WM_STATE_SKIP_TASKBAR") < 0 &&
606 sl.indexOf("_NET_WM_STATE_ABOVE") < 0 &&
607 sl.indexOf("_NET_WM_STATE_BELOW") < 0) {
608 QString cls(X11Tools::windowClass(w));
609 if (isMPlayerClass(cls)) {
610 QString name(X11Tools::windowName(w).toLower());
611 if (isMPlayer(name)) continue;
613 if (wine == None && cls == "explorer.exe") {
614 wine = w;
615 qDebug() << " WINE:" << cls;
616 } else {
617 //FIXME: this will not work as expected!
618 if (f > 0 && wl.at(f-1) == mpw) {
619 res.prepend(w);
620 } else {
621 res << w;
623 qDebug() << " NORM:" << cls;
629 if (wine != None) res << wine;
631 return res;
635 bool Jrugr::deactivateMPlayer () {
636 qDebug() << "onActiveWindowChanged";
637 Window aw = X11Tools::activeWindow();
638 bool changeFocus = false;
640 if (aw != None) {
641 if (X11Tools::windowDesktop(aw) == -1 && isMPlayerClass(X11Tools::windowClass(aw))) {
642 QString name = X11Tools::windowName(aw).toLower();
643 if (isMPlayer(name)) {
644 qDebug() << "MPlayer hack!";
645 changeFocus = true;
648 } else {
649 qDebug() << "Empty window hack!";
650 changeFocus = true;
653 if (changeFocus) {
654 // find previous window
655 Window pw = deskActiveWindow(mCurDesk);
656 int dsk = X11Tools::windowDesktop(pw);
657 if (pw == None || isMPlayer(pw) || (dsk != -1 && dsk != mCurDesk)) {
658 QX11WindowList wl = getPossibleActives(aw);
660 if (wl.size() > 0) pw = wl.at(wl.size()-1); else pw = None;
662 if (pw != None) {
663 qDebug() << "CHANGING FOCUS!" <<
664 "class:" << X11Tools::windowClass(pw) <<
665 "name:" << X11Tools::windowName(pw) <<
666 "pid:" << X11Tools::windowPID(pw);
668 X11Tools::setActiveWindow(pw);
669 return true;
672 return false;
676 void Jrugr::onMPFix () {
677 if (!deactivateMPlayer()) setDeskActiveWindow(mCurDesk, mActiveWindow);
679 #endif
682 void Jrugr::onActiveWindowChanged (Window w) {
683 qDebug() << "onActiveWindowChanged";
684 if (w == None) {
685 #ifdef K8_MPLAYER_HACK
686 if (mDeskJustChanged) {
687 //deactivateMPlayer();
688 if (mMplayerHack) {
689 mMPFix->start(MPLAYER_HACK_TIMEOUT);
691 mDeskJustChanged = false;
693 #else
694 setDeskActiveWindow(mCurDesk, w);
695 #endif
696 mActiveWindow = None;
697 qDebug() << "new active window: NONE";
698 return;
700 qDebug() << "new active window:" << (int)w << "desktop:" << X11Tools::windowDesktop(w);
701 dumpWinInfo("new active window:", w);
703 if (mDeskJustChanged) {
704 qDebug() << "*** mDeskJustChanged ***";
705 mDeskJustChanged = false;
706 #ifdef K8_MPLAYER_HACK
707 if (mMplayerHack && isMPlayer(w)) {
708 //mMPFix->start(MPLAYER_HACK_TIMEOUT);
709 if (deactivateMPlayer()) return;
711 #endif
714 #ifdef K8_MPLAYER_HACK
715 if (!mMplayerHack || !isMPlayer(w))
716 #endif
717 setDeskActiveWindow(mCurDesk, w);
719 WinInfo *wi = findWindowInfo(w), *aw;
720 if (!wi) {
721 qDebug() << "new window";
722 installFacehuggers();
723 wi = findWindowInfo(w);
725 if (wi) {
726 switch (jCfg->switching) {
727 case APP_LAYOUT:
728 if ((aw = findAppInfo(w)) != findAppInfo(mActiveWindow)) {
729 qDebug("application changed!");
730 if (aw) {
731 if (aw->layout != mActiveGroup) {
732 qDebug("enforcing layout %d", aw->layout);
733 emit changeLayout(aw->layout);
735 } else {
736 qWarning("*** APP SHIT! ***");
739 break;
740 case WIN_LAYOUT:
741 if (wi->layout != mActiveGroup) {
742 qDebug("enforcing layout %d", wi->layout);
743 emit changeLayout(wi->layout);
745 break;
746 default: break;
750 mActiveWindow = w;
754 void Jrugr::onClientListChanged () {
755 qDebug() << "onClientListChanged";
756 installFacehuggers();
760 void Jrugr::onActiveDesktopChanged (int desk) {
761 qDebug() << "onActiveDesktopChanged:" << desk;
762 mDeskJustChanged = true;
763 #ifdef K8_MPLAYER_HACK
764 //if (deactivateMPlayer()) mDeskJustChanged = false;
765 if (mMplayerHack) {
766 mMPFix->start(MPLAYER_HACK_TIMEOUT);
768 #endif
769 if (jCfg->switching == DESK_LAYOUT && mCurDesk != desk) {
770 int ll = desktopLayout(desk);
771 setDesktopLayout(desk, ll); // expand desktop list
772 if (ll != mActiveGroup) {
773 qDebug("enforce layout %d for desktop %d", ll, desk);
774 emit changeLayout(mDeskLangs.at(desk));
777 mCurDesk = desk;
781 bool Jrugr::x11EventFilter (XEvent *event) {
783 //qDebug() << "Jrugr::x11EventFilter:" << x11EventName(event);
784 switch (event->type) {
785 case DestroyNotify:
786 windowDies(event->xdestroywindow.window);
787 break;
788 case PropertyNotify:
789 if (event->xproperty.state == PropertyNewValue) {
790 if (atomActWin != None && event->xproperty.atom == atomActWin) {
791 //qDebug() << "emit: activeWindowChanged";
792 emit activeWindowChanged();
794 if (atomCurDesk != None && event->xproperty.atom == atomCurDesk) {
795 //qDebug() << "emit: activeDesktopChanged";
796 emit activeDesktopChanged();
798 if (atomClientList != None && event->xproperty.atom == atomClientList) {
799 qDebug() << "emit: clientListChanged";
800 emit clientListChanged();
803 //qDebug() << "PropertyNotify complete";
804 break;
805 default:
806 if (mXkb) mXkb->processEvent(event);
807 //return false;
808 break;
810 return false; // normal dispatching