Moved wmctrl code to a separate module.
[switcha.git] / switcha.py
blob88bdb22c7d4f04009cbd81720fa1e5e2872ac11e
1 #!/usr/bin/env python
2 import os
3 import sys
5 from PyQt4.QtCore import *
6 from PyQt4.QtGui import *
8 import wmctrl
10 class ListView(QListView):
11 def sizeHint(self):
12 width = 0
13 height = 0
14 options = self.viewOptions()
15 for pos in range(self.model().rowCount()):
16 index = self.model().index(pos, 0)
17 hint = self.itemDelegate().sizeHint(options, index)
18 width = max(width, hint.width())
19 height += hint.height()
20 return QSize(width + 10, height + 10)
23 class Window(QDialog):
24 def __init__(self):
25 QDialog.__init__(self)
26 flags = self.windowFlags()
27 self.setWindowFlags(flags | Qt.FramelessWindowHint)
28 self.initModel()
29 self.initProxyModel()
30 self.initUi()
33 def initModel(self):
34 lst = wmctrl.getWindowList()
35 self._model = QStandardItemModel()
36 for text, wid in lst:
37 item = QStandardItem(unicode(text, "utf8"))
38 data = QVariant(QString(wid))
39 item.setData(data)
40 self._model.appendRow(item)
43 def initProxyModel(self):
44 self._proxyModel = QSortFilterProxyModel()
45 self._proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
46 self._proxyModel.setSourceModel(self._model)
49 def initUi(self):
50 frame = QFrame(self)
51 frame.setFrameStyle(QFrame.Box | QFrame.Plain)
52 layout = QVBoxLayout(self)
53 layout.setMargin(0)
54 layout.addWidget(frame)
56 # LineEdit
57 self._lineEdit = QLineEdit(frame)
58 QObject.connect(self._lineEdit, SIGNAL("textEdited(const QString&)"),
59 self.updateFilter)
60 QObject.connect(self._lineEdit, SIGNAL("returnPressed()"),
61 self.slotReturnPressed)
63 self._lineEdit.installEventFilter(self)
65 # View
66 self._view = ListView(frame)
67 self._view.setModel(self._proxyModel)
68 self._view.setEditTriggers(QAbstractItemView.NoEditTriggers)
69 QObject.connect(self._view, SIGNAL("activated(const QModelIndex&)"),
70 self.switchToWindow)
72 # Layout
73 layout = QVBoxLayout(frame)
74 layout.setMargin(6)
75 layout.addWidget(self._lineEdit)
76 layout.addWidget(self._view)
79 def updateFilter(self, text):
80 self._proxyModel.setFilterFixedString(text)
81 if not self._view.currentIndex().isValid():
82 firstIndex = self._proxyModel.index(0, 0)
83 if firstIndex.isValid():
84 self._view.setCurrentIndex(firstIndex)
87 def eventFilter(self, obj, event):
88 if event.type() != QEvent.KeyPress:
89 return False
91 if event.key() in (Qt.Key_Up, Qt.Key_Down):
92 newEvent = QKeyEvent(event.type(), event.key(), event.modifiers(), event.text())
93 QApplication.postEvent(self._view, newEvent)
94 return True
96 return False
99 def switchToWindow(self, index):
100 sourceIndex = self._proxyModel.mapToSource(index)
101 item = self._model.itemFromIndex(sourceIndex)
102 wid = item.data().toString()
103 wmctrl.switchToWindow(unicode(wid))
104 self.close()
107 def slotReturnPressed(self):
108 index = self._view.currentIndex()
109 if index.isValid():
110 self.switchToWindow(index)
111 else:
112 cmd = unicode(self._lineEdit.text())
113 os.spawnlp(os.P_NOWAIT, 'sh', 'sh', '-c', cmd)
114 self.close()
117 def main():
118 app = QApplication(sys.argv)
119 window = Window()
121 rect = QApplication.desktop().availableGeometry()
122 window.move( \
123 rect.left() + (rect.width() - window.sizeHint().width()) / 2, \
124 rect.top() + (rect.height() - window.sizeHint().height()) / 2 \
126 window.show()
127 app.exec_()
130 if __name__=="__main__":
131 main()