From 48128f268c64f51a93f2defbb4a8b9d72e011e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 13 Feb 2013 00:40:11 +0100 Subject: [PATCH] improve multihead situation prevents the focus being passed to the other head manages OpenGLIsUnsafe setting per head CCBUG: 256242 BUG: 282677 REVIEW: 107853 FIXED-IN: 4.11 --- composite.cpp | 11 +++++++---- tabbox/tabbox.cpp | 43 ++++++------------------------------------- workspace.cpp | 28 ++++++++++++++++++++++++++++ workspace.h | 1 + xcbutils.h | 15 +++++++++++++++ 5 files changed, 57 insertions(+), 41 deletions(-) diff --git a/composite.cpp b/composite.cpp index 36a424823c..e6cb0d484e 100644 --- a/composite.cpp +++ b/composite.cpp @@ -146,6 +146,8 @@ void Compositor::setup() } } +extern int screen_number; // main.cpp + void Compositor::slotCompositingOptionsInitialized() { char selection_name[ 100 ]; @@ -163,14 +165,15 @@ void Compositor::slotCompositingOptionsInitialized() // Some broken drivers crash on glXQuery() so to prevent constant KWin crashes: KSharedConfigPtr unsafeConfigPtr = KGlobal::config(); KConfigGroup unsafeConfig(unsafeConfigPtr, "Compositing"); - if (unsafeConfig.readEntry("OpenGLIsUnsafe", false)) + const QString openGLIsUnsafe = "OpenGLIsUnsafe" + QString::number(screen_number); + if (unsafeConfig.readEntry(openGLIsUnsafe, false)) kWarning(1212) << "KWin has detected that your OpenGL library is unsafe to use"; else { - unsafeConfig.writeEntry("OpenGLIsUnsafe", true); + unsafeConfig.writeEntry(openGLIsUnsafe, true); unsafeConfig.sync(); #ifndef KWIN_HAVE_OPENGLES if (!CompositingPrefs::hasGlx()) { - unsafeConfig.writeEntry("OpenGLIsUnsafe", false); + unsafeConfig.writeEntry(openGLIsUnsafe, false); unsafeConfig.sync(); kDebug(1212) << "No glx extensions available"; break; @@ -180,7 +183,7 @@ void Compositor::slotCompositingOptionsInitialized() m_scene = SceneOpenGL::createScene(); // TODO: Add 30 second delay to protect against screen freezes as well - unsafeConfig.writeEntry("OpenGLIsUnsafe", false); + unsafeConfig.writeEntry(openGLIsUnsafe, false); unsafeConfig.sync(); if (m_scene && !m_scene->initFailed()) diff --git a/tabbox/tabbox.cpp b/tabbox/tabbox.cpp index cb2120f53f..0d23daa670 100644 --- a/tabbox/tabbox.cpp +++ b/tabbox/tabbox.cpp @@ -912,8 +912,9 @@ static bool areModKeysDepressed(const KShortcut& cut) void TabBox::navigatingThroughWindows(bool forward, const KShortcut& shortcut, TabBoxMode mode) { - if (isGrabbed()) + if (!m_ready || isGrabbed() || !Workspace::self()->isOnCurrentHead()) { return; + } if (!options->focusPolicyIsReasonable()) { //ungrabXKeyboard(); // need that because of accelerator raw mode // CDE style raise / lower @@ -931,75 +932,49 @@ void TabBox::navigatingThroughWindows(bool forward, const KShortcut& shortcut, T void TabBox::slotWalkThroughWindows() { - if (!m_ready){ - return; - } navigatingThroughWindows(true, m_cutWalkThroughWindows, TabBoxWindowsMode); } void TabBox::slotWalkBackThroughWindows() { - if (!m_ready){ - return; - } navigatingThroughWindows(false, m_cutWalkThroughWindowsReverse, TabBoxWindowsMode); } void TabBox::slotWalkThroughWindowsAlternative() { - if (!m_ready){ - return; - } navigatingThroughWindows(true, m_cutWalkThroughWindowsAlternative, TabBoxWindowsAlternativeMode); } void TabBox::slotWalkBackThroughWindowsAlternative() { - if (!m_ready){ - return; - } navigatingThroughWindows(false, m_cutWalkThroughWindowsAlternativeReverse, TabBoxWindowsAlternativeMode); } void TabBox::slotWalkThroughCurrentAppWindows() { - if (!m_ready){ - return; - } navigatingThroughWindows(true, m_cutWalkThroughCurrentAppWindows, TabBoxCurrentAppWindowsMode); } void TabBox::slotWalkBackThroughCurrentAppWindows() { - if (!m_ready){ - return; - } navigatingThroughWindows(false, m_cutWalkThroughCurrentAppWindowsReverse, TabBoxCurrentAppWindowsMode); } void TabBox::slotWalkThroughCurrentAppWindowsAlternative() { - if (!m_ready){ - return; - } navigatingThroughWindows(true, m_cutWalkThroughCurrentAppWindowsAlternative, TabBoxCurrentAppWindowsAlternativeMode); } void TabBox::slotWalkBackThroughCurrentAppWindowsAlternative() { - if (!m_ready){ - return; - } navigatingThroughWindows(false, m_cutWalkThroughCurrentAppWindowsAlternativeReverse, TabBoxCurrentAppWindowsAlternativeMode); } void TabBox::slotWalkThroughDesktops() { - if (!m_ready){ + if (!m_ready || isGrabbed() || !Workspace::self()->isOnCurrentHead()) { return; } - if (isGrabbed()) - return; if (areModKeysDepressed(m_cutWalkThroughDesktops)) { if (startWalkThroughDesktops()) walkThroughDesktops(true); @@ -1010,11 +985,9 @@ void TabBox::slotWalkThroughDesktops() void TabBox::slotWalkBackThroughDesktops() { - if (!m_ready){ + if (!m_ready || isGrabbed() || !Workspace::self()->isOnCurrentHead()) { return; } - if (isGrabbed()) - return; if (areModKeysDepressed(m_cutWalkThroughDesktopsReverse)) { if (startWalkThroughDesktops()) walkThroughDesktops(false); @@ -1025,11 +998,9 @@ void TabBox::slotWalkBackThroughDesktops() void TabBox::slotWalkThroughDesktopList() { - if (!m_ready){ + if (!m_ready || isGrabbed() || !Workspace::self()->isOnCurrentHead()) { return; } - if (isGrabbed()) - return; if (areModKeysDepressed(m_cutWalkThroughDesktopList)) { if (startWalkThroughDesktopList()) walkThroughDesktops(true); @@ -1040,11 +1011,9 @@ void TabBox::slotWalkThroughDesktopList() void TabBox::slotWalkBackThroughDesktopList() { - if (!m_ready){ + if (!m_ready || isGrabbed() || !Workspace::self()->isOnCurrentHead()) { return; } - if (isGrabbed()) - return; if (areModKeysDepressed(m_cutWalkThroughDesktopListReverse)) { if (startWalkThroughDesktopList()) walkThroughDesktops(false); diff --git a/workspace.cpp b/workspace.cpp index 8f7e450d68..97d1f321c4 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1606,6 +1606,34 @@ void Workspace::checkActiveScreen(const Client* c) active_screen = c->screen(); } +/** + * checks whether the X Window with the input focus is on our X11 screen + * if the window cannot be determined or inspected, resturn depends on whether there's actually + * more than one screen + * + * this is NOT in any way related to XRandR multiscreen + * + */ +extern bool is_multihead; // main.cpp +bool Workspace::isOnCurrentHead() +{ + if (!is_multihead) { + return true; + } + + Xcb::CurrentInput currentInput; + if (currentInput.window() == XCB_WINDOW_NONE) { + return !is_multihead; + } + + Xcb::WindowGeometry geometry(currentInput.window()); + if (geometry.isNull()) { // should not happen + return !is_multihead; + } + + return rootWindow() == geometry->root; +} + /** * Called e.g. when a user clicks on a window, set active screen to be the screen * where the click occurred diff --git a/workspace.h b/workspace.h index d5b6342d35..e033ac9832 100644 --- a/workspace.h +++ b/workspace.h @@ -223,6 +223,7 @@ public: int activeScreen() const; int numScreens() const; void checkActiveScreen(const Client* c); + bool isOnCurrentHead(); void setActiveScreenMouse(const QPoint& mousepos); QRect screenGeometry(int screen) const; int screenNumber(const QPoint& pos) const; diff --git a/xcbutils.h b/xcbutils.h index 9d54803974..2996273f76 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -178,6 +178,21 @@ public: } }; +inline xcb_get_input_focus_cookie_t get_input_focus(xcb_connection_t *c, xcb_window_t) { + return xcb_get_input_focus(c); +} +class CurrentInput : public Wrapper +{ +public: + CurrentInput() : Wrapper() {} + + inline xcb_window_t window() { + if (isNull()) + return XCB_WINDOW_NONE; + return (*this)->focus; + } +}; + class ExtensionData { public: