21#if KWIN_BUILD_ACTIVITIES
24#include "compositor.h"
32#include "virtualdesktops.h"
40#include <KConfigGroup>
41#include <KGlobalAccel>
42#include <KLazyLocalizedString>
43#include <KLocalizedString>
44#include <kkeyserver.h>
46#include <X11/keysym.h>
47#include <X11/keysymdef.h>
49#include <xcb/xcb_keysyms.h>
79 return VirtualDesktopManager::self()->currentDesktop()->name();
102bool TabBoxHandlerImpl::checkDesktop(
Window *client)
const
104 switch (
config().clientDesktopMode()) {
114bool TabBoxHandlerImpl::checkActivity(
Window *client)
const
116 switch (
config().clientActivitiesMode()) {
126bool TabBoxHandlerImpl::checkApplications(
Window *client)
const
130 switch (
config().clientApplicationsMode()) {
133 for (
const Window *other : list) {
148bool TabBoxHandlerImpl::checkMinimized(
Window *client)
const
150 switch (
config().clientMinimizedMode()) {
160bool TabBoxHandlerImpl::checkMultiScreen(
Window *client)
const
162 switch (
config().clientMultiScreenMode()) {
179 bool addClient = checkDesktop(
client)
181 && checkApplications(
client)
183 && checkMultiScreen(
client);
188 if (modal ==
nullptr || modal ==
client) {
205 for (
Window *window : stacking) {
206 if (window->isClient()) {
250 if (window->isClient() && window->isDesktop() && window->isOnCurrentDesktop() && window->output() ==
workspace()->
activeOutput()) {
267 QList<EffectWindow *> windows;
272 windows << t->effectWindow();
287 : m_displayRefcount(0)
289 , m_noModifierGrab(false)
290 , m_forcedGlobalMouseGrab(false)
314 m_defaultCurrentApplicationConfig = m_defaultConfig;
317 m_alternativeCurrentApplicationConfig = m_alternativeConfig;
324 connect(&m_delayedShowTimer, &QTimer::timeout,
this, &
TabBox::show);
337template<
typename Slot>
338void TabBox::key(
const KLazyLocalizedString &actionName, Slot slot,
const QKeySequence &shortcut)
340 QAction *a =
new QAction(
this);
341 a->setProperty(
"componentName", QStringLiteral(
"kwin"));
342 a->setObjectName(QString::fromUtf8(actionName.untranslatedText()));
343 a->setText(actionName.toString());
344 KGlobalAccel::self()->setGlobalShortcut(a, QList<QKeySequence>() << shortcut);
345 connect(a, &QAction::triggered,
this, slot);
346 auto cuts = KGlobalAccel::self()->shortcut(a);
347 globalShortcutChanged(a, cuts.isEmpty() ? QKeySequence() : cuts.first());
350static constexpr const auto s_windows = kli18n(
"Walk Through Windows");
351static constexpr const auto s_windowsRev = kli18n(
"Walk Through Windows (Reverse)");
352static constexpr const auto s_windowsAlt = kli18n(
"Walk Through Windows Alternative");
353static constexpr const auto s_windowsAltRev = kli18n(
"Walk Through Windows Alternative (Reverse)");
354static constexpr const auto s_app = kli18n(
"Walk Through Windows of Current Application");
355static constexpr const auto s_appRev = kli18n(
"Walk Through Windows of Current Application (Reverse)");
356static constexpr const auto s_appAlt = kli18n(
"Walk Through Windows of Current Application Alternative");
357static constexpr const auto s_appAltRev = kli18n(
"Walk Through Windows of Current Application Alternative (Reverse)");
370 connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged,
this, &TabBox::globalShortcutChanged);
373void TabBox::globalShortcutChanged(QAction *action,
const QKeySequence &seq)
375 if (qstrcmp(qPrintable(action->objectName()), s_windows.untranslatedText()) == 0) {
376 m_cutWalkThroughWindows = seq;
377 }
else if (qstrcmp(qPrintable(action->objectName()), s_windowsRev.untranslatedText()) == 0) {
378 m_cutWalkThroughWindowsReverse = seq;
379 }
else if (qstrcmp(qPrintable(action->objectName()), s_app.untranslatedText()) == 0) {
380 m_cutWalkThroughCurrentAppWindows = seq;
381 }
else if (qstrcmp(qPrintable(action->objectName()), s_appRev.untranslatedText()) == 0) {
382 m_cutWalkThroughCurrentAppWindowsReverse = seq;
383 }
else if (qstrcmp(qPrintable(action->objectName()), s_windowsAlt.untranslatedText()) == 0) {
384 m_cutWalkThroughWindowsAlternative = seq;
385 }
else if (qstrcmp(qPrintable(action->objectName()), s_windowsAltRev.untranslatedText()) == 0) {
386 m_cutWalkThroughWindowsAlternativeReverse = seq;
387 }
else if (qstrcmp(qPrintable(action->objectName()), s_appAlt.untranslatedText()) == 0) {
388 m_cutWalkThroughCurrentAppWindowsAlternative = seq;
389 }
else if (qstrcmp(qPrintable(action->objectName()), s_appAltRev.untranslatedText()) == 0) {
390 m_cutWalkThroughCurrentAppWindowsAlternativeReverse = seq;
402 m_tabBox->
setConfig(m_alternativeConfig);
405 m_tabBox->
setConfig(m_defaultCurrentApplicationConfig);
408 m_tabBox->
setConfig(m_alternativeCurrentApplicationConfig);
416 if (!partial_reset) {
464 if (!index.isValid()) {
488 m_delayedShowTimer.stop();
495 qCDebug(KWIN_TABBOX) <<
"Tab box was not properly closed by an effect";
497 m_tabBox->
hide(abort);
500void TabBox::reconfigure()
502 KSharedConfigPtr c = kwinApp()->config();
503 KConfigGroup config = c->group(QStringLiteral(
"TabBox"));
505 loadConfig(c->group(QStringLiteral(
"TabBox")), m_defaultConfig);
506 loadConfig(c->group(QStringLiteral(
"TabBoxAlternative")), m_alternativeConfig);
508 m_defaultCurrentApplicationConfig = m_defaultConfig;
510 m_alternativeCurrentApplicationConfig = m_alternativeConfig;
515 m_delayShowTime = config.readEntry<
int>(
"DelayTime", 90);
517 QList<ElectricBorder> *borders = &m_borderActivate;
518 QString borderConfig = QStringLiteral(
"BorderActivate");
519 for (
int i = 0; i < 2; ++i) {
524 QStringList list = config.readEntry(borderConfig, QStringList());
525 for (
const QString &s : std::as_const(list)) {
527 const int i = s.toInt(&ok);
534 borders = &m_borderAlternativeActivate;
535 borderConfig = QStringLiteral(
"BorderAlternativeActivate");
538 auto touchConfig = [
this, config](
const QString &key, QHash<ElectricBorder, QAction *> &actions,
TabBoxMode mode,
const QStringList &defaults = QStringList{}) {
540 for (
auto it = actions.begin(); it != actions.end();) {
542 it = actions.erase(it);
545 const QStringList list = config.readEntry(key, defaults);
546 for (
const auto &s : list) {
548 const int i = s.toInt(&ok);
552 QAction *a =
new QAction(
this);
553 connect(a, &QAction::triggered,
this, std::bind(&TabBox::toggleMode,
this,
mode));
558 touchConfig(QStringLiteral(
"TouchBorderActivate"), m_touchActivate,
TabBoxWindowsMode);
562void TabBox::loadConfig(
const KConfigGroup &config, TabBoxConfig &tabBoxConfig)
581 tabBoxConfig.setShowTabBox(config.readEntry<
bool>(
"ShowTabBox",
583 tabBoxConfig.setHighlightWindows(config.readEntry<
bool>(
"HighlightWindows",
591 if (
isDisplayed() || m_delayedShowTimer.isActive()) {
596 if (!m_delayShowTime) {
601 m_delayedShowTimer.setSingleShot(
true);
602 m_delayedShowTimer.start(m_delayShowTime);
613 switch (event->type()) {
614 case QEvent::MouseMove:
621 case QEvent::MouseButtonPress:
627 case QEvent::MouseButtonRelease:
643 if (event->angleDelta().y() == 0) {
646 const QModelIndex index = m_tabBox->
nextPrev(event->angleDelta().y() > 0);
647 if (index.isValid()) {
660 if (m_noModifierGrab) {
661 if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return || event->key() == Qt::Key_Space) {
673 xcb_key_symbols_free(symbols);
680static bool areKeySymXsDepressed(
const uint keySyms[],
int nKeySyms)
684 std::unique_ptr<xcb_key_symbols_t, KeySymbolsDeleter> symbols(xcb_key_symbols_alloc(
connection()));
685 if (!symbols || !keys) {
688 const auto keymap = keys->keys;
690 bool depressed =
false;
691 for (
int iKeySym = 0; iKeySym < nKeySyms; iKeySym++) {
692 uint keySymX = keySyms[iKeySym];
693 xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(symbols.get(), keySymX);
699 while (keyCodes[j] != XCB_NO_SYMBOL) {
700 const xcb_keycode_t keyCodeX = keyCodes[j++];
701 int i = keyCodeX / 8;
702 char mask = 1 << (keyCodeX - (i * 8));
704 if (i < 0 || i >= 32) {
708 qCDebug(KWIN_TABBOX) << iKeySym <<
": keySymX=0x" << QString::number(keySymX, 16)
709 <<
" i=" << i <<
" mask=0x" << QString::number(mask, 16)
710 <<
" keymap[i]=0x" << QString::number(keymap[i], 16);
712 if (keymap[i] & mask) {
724static bool areModKeysDepressedX11(
const QKeySequence &seq)
728 int mod = seq[seq.count() - 1] & Qt::KeyboardModifierMask;
730 if (mod & Qt::SHIFT) {
731 rgKeySyms[nKeySyms++] = XK_Shift_L;
732 rgKeySyms[nKeySyms++] = XK_Shift_R;
734 if (mod & Qt::CTRL) {
735 rgKeySyms[nKeySyms++] = XK_Control_L;
736 rgKeySyms[nKeySyms++] = XK_Control_R;
739 rgKeySyms[nKeySyms++] = XK_Alt_L;
740 rgKeySyms[nKeySyms++] = XK_Alt_R;
742 if (mod & Qt::META) {
746 rgKeySyms[nKeySyms++] = XK_Super_L;
747 rgKeySyms[nKeySyms++] = XK_Super_R;
748 rgKeySyms[nKeySyms++] = XK_Meta_L;
749 rgKeySyms[nKeySyms++] = XK_Meta_R;
752 return areKeySymXsDepressed(rgKeySyms, nKeySyms);
755static bool areModKeysDepressedWayland(
const QKeySequence &seq)
757 const int mod = seq[seq.count() - 1] & Qt::KeyboardModifierMask;
759 if ((mod & Qt::SHIFT) && mods.testFlag(Qt::ShiftModifier)) {
762 if ((mod & Qt::CTRL) && mods.testFlag(Qt::ControlModifier)) {
765 if ((mod & Qt::ALT) && mods.testFlag(Qt::AltModifier)) {
768 if ((mod & Qt::META) && mods.testFlag(Qt::MetaModifier)) {
774static bool areModKeysDepressed(
const QKeySequence &seq)
779 if (kwinApp()->shouldUseWaylandForCompositing()) {
780 return areModKeysDepressedWayland(seq);
782 return areModKeysDepressedX11(seq);
786void TabBox::navigatingThroughWindows(
bool forward,
const QKeySequence &shortcut,
TabBoxMode mode)
794 CDEWalkThroughWindows(forward);
796 if (areModKeysDepressed(shortcut)) {
797 if (startKDEWalkThroughWindows(
mode)) {
798 KDEWalkThroughWindows(forward);
803 KDEOneStepThroughWindows(forward,
mode);
815 navigatingThroughWindows(
false, m_cutWalkThroughWindowsReverse,
TabBoxWindowsMode);
848void TabBox::shadeActivate(
Window *c)
857 if (m_borderAlternativeActivate.contains(eb)) {
873 if (!establishTabBoxGrab()) {
876 m_noModifierGrab = m_tabGrab =
true;
883bool TabBox::startKDEWalkThroughWindows(
TabBoxMode mode)
885 if (!establishTabBoxGrab()) {
889 m_noModifierGrab =
false;
895void TabBox::KDEWalkThroughWindows(
bool forward)
901void TabBox::CDEWalkThroughWindows(
bool forward)
908 for (
int i =
Workspace::self()->stackingOrder().size() - 1; i >= 0; --i) {
910 if (t->isClient() && t->isOnCurrentActivity() && t->isOnCurrentDesktop() && !t->isSpecialWindow()
911 && !t->isShade() && t->isShown() && t->wantsTabFocus()
912 && !t->keepAbove() && !t->keepBelow()) {
918 bool options_traverse_all;
920 KConfigGroup group(kwinApp()->config(), QStringLiteral(
"TabBox"));
921 options_traverse_all = group.readEntry(
"TraverseAll",
false);
924 Window *firstClient =
nullptr;
931 }
else if (nc == firstClient) {
936 }
while (nc && nc != c && ((!options_traverse_all && !nc->isOnCurrentDesktop()) || nc->isMinimized() || !nc->wantsTabFocus() || nc->keepAbove() || nc->keepBelow() || !nc->isOnCurrentActivity()));
945 if (!nc->isOnCurrentDesktop()) {
946 VirtualDesktopManager::self()->setCurrent(nc->desktops().constLast());
953void TabBox::KDEOneStepThroughWindows(
bool forward,
TabBoxMode mode)
971 Direction direction(Steady);
973 auto contains = [](
const QKeySequence &shortcut,
int key) ->
bool {
974 for (
int i = 0; i < shortcut.count(); ++i) {
975 if (shortcut[i] == key) {
983 auto directionFor = [keyQt, contains](
const QKeySequence &forward,
const QKeySequence &backward) -> Direction {
984 if (contains(forward, keyQt)) {
987 if (contains(backward, keyQt)) {
990 if (!(keyQt & Qt::ShiftModifier)) {
997 Qt::KeyboardModifiers mods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier;
999 if (((keyQt & ~mods) == Qt::Key_Tab) || ((keyQt & ~mods) == Qt::Key_Backtab)) {
1000 if (contains(forward, mods | Qt::Key_Backtab) || contains(forward, mods | Qt::Key_Tab)) {
1003 if (contains(backward, mods | Qt::Key_Backtab) || contains(backward, mods | Qt::Key_Tab)) {
1010 if (contains(forward, keyQt & ~Qt::ShiftModifier)) {
1013 if (contains(backward, keyQt & ~Qt::ShiftModifier)) {
1021 static const int ModeCount = 4;
1025 const QKeySequence cuts[2 * ModeCount] = {
1027 m_cutWalkThroughWindows, m_cutWalkThroughWindowsAlternative,
1028 m_cutWalkThroughCurrentAppWindows, m_cutWalkThroughCurrentAppWindowsAlternative,
1030 m_cutWalkThroughWindowsReverse, m_cutWalkThroughWindowsAlternativeReverse,
1031 m_cutWalkThroughCurrentAppWindowsReverse, m_cutWalkThroughCurrentAppWindowsAlternativeReverse};
1032 bool testedCurrent =
false;
1035 if (!testedCurrent && modes[i] !=
mode()) {
1037 i = (i + 1) % ModeCount;
1040 if (testedCurrent && modes[i] ==
mode()) {
1043 testedCurrent =
true;
1044 direction = directionFor(cuts[i], cuts[i + ModeCount]);
1045 if (direction != Steady) {
1046 if (modes[i] !=
mode()) {
1049 auto replayWithChangedTabboxMode = [
this, direction]() {
1053 QTimer::singleShot(50,
this, replayWithChangedTabboxMode);
1056 }
else if (++j > 2 * ModeCount) {
1057 qCDebug(KWIN_TABBOX) <<
"Invalid TabBoxMode";
1060 i = (i + 1) % ModeCount;
1062 if (direction != Steady) {
1063 qCDebug(KWIN_TABBOX) <<
"== " << cuts[i].toString() <<
" or " << cuts[i + ModeCount].toString();
1064 KDEWalkThroughWindows(direction == Forward);
1069 if (((keyQt & ~Qt::KeyboardModifierMask) == Qt::Key_Escape) && direction == Steady) {
1072 }
else if (direction == Steady) {
1073 QKeyEvent event(QEvent::KeyPress, keyQt & ~Qt::KeyboardModifierMask, Qt::NoModifier);
1087 m_noModifierGrab =
false;
1107 if (m_noModifierGrab) {
1122 if (!c || list.isEmpty()) {
1127 return list.first();
1129 for (
int i =
reference + 1; i < list.count(); ++i) {
1130 Window *candidate = list[i];
1137 Window *candidate = list[i];
1152 if (!c || list.isEmpty()) {
1159 for (
int i =
reference - 1; i >= 0; --i) {
1160 Window *candidate = list[i];
1166 for (
int i = list.size() - 1; i >
reference; --i) {
1167 Window *candidate = list[i];
1175bool TabBox::establishTabBoxGrab()
1177 if (kwinApp()->shouldUseWaylandForCompositing()) {
1178 m_forcedGlobalMouseGrab =
true;
1181 kwinApp()->updateXTime();
1190 Q_ASSERT(!m_forcedGlobalMouseGrab);
1191 m_forcedGlobalMouseGrab =
true;
1195 m_x11EventFilter = std::make_unique<X11Filter>();
1199void TabBox::removeTabBoxGrab()
1201 if (kwinApp()->shouldUseWaylandForCompositing()) {
1202 m_forcedGlobalMouseGrab =
false;
1205 kwinApp()->updateXTime();
1207 Q_ASSERT(m_forcedGlobalMouseGrab);
1208 m_forcedGlobalMouseGrab =
false;
1212 m_x11EventFilter.reset();
1217#include "moc_tabbox.cpp"
static bool compositing()
Static check to test whether the Compositor is available and active.
void highlightWindows(const QList< EffectWindow * > &windows)
bool checkInputWindowEvent(QMouseEvent *e)
bool contains(Window *window) const
Checks whether the most recently used focus chain contains the given window.
Window * firstMostRecentlyUsed() const
Returns the first Window in the most recently used focus chain. First Window in this case means reall...
Window * nextMostRecentlyUsed(Window *reference) const
Queries the most recently used focus chain for the next Window after the given reference Window.
bool isShadeHover() const
bool focusPolicyIsReasonable
void reserve(ElectricBorder border, QObject *object, const char *callback)
void unreserve(ElectricBorder border, QObject *object)
void reserveTouch(ElectricBorder border, QAction *action, TouchCallback::CallbackFunction callback=nullptr)
@ AllActivitiesClients
Windows from all Activities are included.
@ OnlyCurrentActivityClients
Only Windows on current activity are included.
@ ExcludeCurrentActivityClients
Exclude Windows on current activity.
static ClientSwitchingMode defaultSwitchingMode()
@ OnlyMinimizedClients
Only minimized Windows are included.
@ IgnoreMinimizedStatus
Windows are included no matter they are minimized or not.
@ ExcludeMinimizedClients
Exclude minimized Windows.
void setClientMinimizedMode(ClientMinimizedMode minimizedMode)
void setClientActivitiesMode(ClientActivitiesMode activitiesMode)
@ OneWindowPerApplication
Only one Window for each application is included.
@ AllWindowsAllApplications
Windows from all applications are included.
@ AllWindowsCurrentApplication
Only Windows for the current application are included.
static ClientActivitiesMode defaultActivitiesMode()
bool isHighlightWindows() const
void setClientApplicationsMode(ClientApplicationsMode applicationsMode)
static ClientMultiScreenMode defaultMultiScreenMode()
@ AllDesktopsClients
Windows from all desktops are included.
@ OnlyCurrentDesktopClients
Only Windows on current desktop are included.
@ ExcludeCurrentDesktopClients
Exclude Windows on current desktop.
static OrderMinimizedMode defaultOrderMinimizedMode()
static ClientApplicationsMode defaultApplicationsMode()
@ NoGroupByMinimized
Windows are not grouped by whether they are minimized.
static QString defaultLayoutName()
void setClientMultiScreenMode(ClientMultiScreenMode multiScreenMode)
@ FocusChainSwitching
Sort by recently used. Most recently used Window is the first.
static ShowDesktopMode defaultShowDesktopMode()
static ClientMinimizedMode defaultMinimizedMode()
void setOrderMinimizedMode(OrderMinimizedMode orderMinimizedMode)
void setShowDesktopMode(ShowDesktopMode showDesktopMode)
@ DoNotShowDesktopClient
A Window representing the desktop is not included.
@ ExcludeCurrentScreenClients
Exclude Windows from the current screen.
@ IgnoreMultiScreen
Windows are included independently of the screen they are on.
static bool defaultHighlightWindow()
void setClientSwitchingMode(ClientSwitchingMode switchingMode)
static bool defaultShowTabBox()
void setClientDesktopMode(ClientDesktopMode desktopMode)
static ClientDesktopMode defaultDesktopMode()
void createModel(bool partialReset=false)
const QModelIndex & currentIndex() const
bool containsPos(const QPoint &pos) const
void setConfig(const TabBoxConfig &config)
void hide(bool abort=false)
QList< Window * > clientList() const
virtual void grabbedKeyEvent(QKeyEvent *event) const
QModelIndex nextPrev(bool forward) const
Window * client(const QModelIndex &index) const
QModelIndex index(Window *client) const
const TabBoxConfig & config() const
virtual Window * activeClient() const =0
void setCurrentIndex(const QModelIndex &index)
QModelIndex first() const
Window * desktopClient() const override
QList< Window * > stackingOrder() const override
void shadeClient(Window *c, bool b) const override
void activateAndClose() override
Window * nextClientFocusChain(Window *client) const override
void restack(Window *c, Window *under) override
Window * clientToAddToList(Window *client) const override
void elevateClient(Window *c, QWindow *tabbox, bool elevate) const override
bool isKWinCompositing() const override
TabBoxHandlerImpl(TabBox *tabBox)
int activeScreen() const override
QString desktopName(Window *client) const override
Window * firstClientFocusChain() const override
Window * activeClient() const override
void highlightWindows(Window *window=nullptr, QWindow *controller=nullptr) override
bool noModifierGrab() const override
bool isInFocusChain(Window *client) const override
~TabBoxHandlerImpl() override
void raiseClient(Window *client) const override
bool handleMouseEvent(QMouseEvent *event)
Window * previousClientStatic(Window *) const
QList< Window * > currentClientList()
bool toggle(ElectricBorder eb)
void close(bool abort=false)
void grabbedKeyEvent(QKeyEvent *event)
void slotWalkBackThroughCurrentAppWindows()
void hide(bool abort=false)
void setCurrentIndex(QModelIndex index, bool notifyEffects=true)
void slotWalkThroughWindowsAlternative()
void slotWalkThroughCurrentAppWindows()
void reset(bool partial_reset=false)
void nextPrev(bool next=true)
void accept(bool closeTabBox=true)
Window * nextClientStatic(Window *) const
void slotWalkBackThroughWindowsAlternative()
void slotWalkThroughCurrentAppWindowsAlternative()
void slotWalkBackThroughWindows()
void slotWalkBackThroughCurrentAppWindowsAlternative()
void setMode(TabBoxMode mode)
void setCurrentClient(Window *newClient)
void tabBoxKeyEvent(QKeyEvent *)
void slotWalkThroughWindows()
bool handleWheelEvent(QWheelEvent *event)
bool noModifierGrab() const
virtual bool isClient() const
virtual void updateMouseGrab()
EffectWindow * effectWindow()
bool wantsTabFocus() const
bool isOnCurrentActivity() const
static bool belongToSameApplication(const Window *c1, const Window *c2, SameApplicationChecks checks=SameApplicationChecks())
bool isOnAllDesktops() const
bool isOnCurrentDesktop() const
void elevate(bool elevate)
QList< KWin::VirtualDesktop * > desktops
ShadeMode shadeMode() const
void cancelShadeHoverTimer()
virtual Window * findModal(bool allow_itself=false)=0
Window * activeWindow() const
ScreenEdges * screenEdges() const
void activateWindow(Window *window, bool force=false)
const QList< Window * > & stackingOrder() const
Output * activeOutput() const
void restack(Window *window, Window *under, bool force=false)
void raiseWindow(Window *window, bool nogroup=false)
static Workspace * self()
FocusChain * focusChain() const
void lowerWindow(Window *window, bool nogroup=false)
QList< Output * > outputs() const
const QList< Window * > windows() const
void setShowingDesktop(bool showing, bool animated=true)
KWIN_EXPORT xcb_connection_t * connection()
@ TabBoxCurrentAppWindowsMode
@ TabBoxCurrentAppWindowsAlternativeMode
@ TabBoxWindowsAlternativeMode
void KWIN_EXPORT ungrabXKeyboard()
InputRedirection * input()
bool KWIN_EXPORT grabXKeyboard(xcb_window_t w=XCB_WINDOW_NONE)
void operator()(xcb_key_symbols_t *symbols)
struct _XCBKeySymbols xcb_key_symbols_t