From eb2387c5815e87b64823f622ebe585e8769a6c34 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Wed, 26 Apr 2017 16:50:49 +0300 Subject: [PATCH] fix configuration window positioning and issues --draw the wayland surfaces for docks and config views earlier. That way we are certain that the signals wont mess up the experience. This way positioning config views and getting the focusOut event works correctly --disable in waylandinterface any x specific code. In order to be ready that class to accept only wayland centered code --- app/dockconfigview.cpp | 61 +++++++++++++++------- app/dockconfigview.h | 2 + app/dockview.cpp | 10 ++++ app/waylandinterface.cpp | 109 ++++++++++++++++++++------------------- 4 files changed, 109 insertions(+), 73 deletions(-) diff --git a/app/dockconfigview.cpp b/app/dockconfigview.cpp index 60a0bc37d..6406ff76f 100644 --- a/app/dockconfigview.cpp +++ b/app/dockconfigview.cpp @@ -45,6 +45,8 @@ DockConfigView::DockConfigView(Plasma::Containment *containment, DockView *dockV m_blockFocusLost(false), m_dockView(dockView) { + setupWaylandIntegration(); + setScreen(m_dockView->screen()); if (containment) { @@ -83,6 +85,12 @@ DockConfigView::~DockConfigView() foreach (auto var, connections) { QObject::disconnect(var); } + + if (m_shellSurface) { + delete m_shellSurface; + m_shellSurface = nullptr; + } + } void DockConfigView::init() @@ -274,38 +282,53 @@ void DockConfigView::focusOutEvent(QFocusEvent *ev) } } +void DockConfigView::setupWaylandIntegration() +{ + if (m_shellSurface) { + // already setup + return; + } + + if (DockCorona *c = qobject_cast(m_dockView->containment()->corona())) { + using namespace KWayland::Client; + PlasmaShell *interface = c->waylandDockCoronaInterface(); + + if (!interface) { + return; + } + + Surface *s = Surface::fromWindow(this); + + if (!s) { + return; + } + + qDebug() << "wayland dock window surface was created..."; + + m_shellSurface = interface->createSurface(s, this); + } +} + bool DockConfigView::event(QEvent *e) { if (e->type() == QEvent::PlatformSurface) { if (auto pe = dynamic_cast(e)) { switch (pe->surfaceEventType()) { case QPlatformSurfaceEvent::SurfaceCreated: + if (m_shellSurface) { break; } - if (DockCorona *c = qobject_cast(m_dockView->containment()->corona())) { - using namespace KWayland::Client; - PlasmaShell *interface = c->waylandDockCoronaInterface(); - - if (!interface) { - break; - } - - Surface *s = Surface::fromWindow(this); - - if (!s) { - break; - } - - m_shellSurface = interface->createSurface(s, this); - } - + setupWaylandIntegration(); break; case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: - delete m_shellSurface; - m_shellSurface = nullptr; + if (m_shellSurface) { + delete m_shellSurface; + m_shellSurface = nullptr; + } + PanelShadows::self()->removeWindow(this); break; } diff --git a/app/dockconfigview.h b/app/dockconfigview.h index 8f4ab39e5..9e1a37be7 100644 --- a/app/dockconfigview.h +++ b/app/dockconfigview.h @@ -82,6 +82,8 @@ signals: void aboutApplication(); private: + void setupWaylandIntegration(); + bool m_blockFocusLost; QPointer m_dockView; diff --git a/app/dockview.cpp b/app/dockview.cpp index 2405b082e..8e3c96e93 100644 --- a/app/dockview.cpp +++ b/app/dockview.cpp @@ -58,6 +58,8 @@ DockView::DockView(Plasma::Corona *corona, QScreen *targetScreen, bool dockWindo : PlasmaQuick::ContainmentView(corona), m_contextMenu(nullptr) { + setupWaylandIntegration(); + setVisible(false); setTitle(corona->kPackage().metadata().name()); setIcon(qGuiApp->windowIcon()); @@ -147,6 +149,11 @@ DockView::~DockView() if (m_visibility) delete m_visibility; + + if (m_shellSurface) { + delete m_shellSurface; + m_shellSurface = nullptr; + } } void DockView::init() @@ -1164,6 +1171,8 @@ bool DockView::event(QEvent *e) KWayland::Client::PlasmaShellSurface::PanelBehavior behavior; behavior = KWayland::Client::PlasmaShellSurface::PanelBehavior::WindowsGoBelow; + qDebug() << "wayland dock window surface was created..."; + m_shellSurface->setRole(KWayland::Client::PlasmaShellSurface::Role::Panel); m_shellSurface->setSkipTaskbar(true); m_shellSurface->setPanelBehavior(behavior); @@ -1179,6 +1188,7 @@ bool DockView::event(QEvent *e) case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: delete m_shellSurface; + qDebug() << "wayland dock window surface was deleted..."; m_shellSurface = nullptr; PanelShadows::self()->removeWindow(this); break; diff --git a/app/waylandinterface.cpp b/app/waylandinterface.cpp index 910b1efe4..ebbc0ee98 100644 --- a/app/waylandinterface.cpp +++ b/app/waylandinterface.cpp @@ -64,9 +64,9 @@ WaylandInterface::WaylandInterface(QObject *parent) , this, &WaylandInterface::currentActivityChanged); // fill windows list - foreach (const auto &wid, KWindowSystem::self()->windows()) { - addWindow(wid); - } + /* foreach (const auto &wid, KWindowSystem::self()->windows()) { + addWindow(wid); + }*/ } WaylandInterface::~WaylandInterface() @@ -75,8 +75,8 @@ WaylandInterface::~WaylandInterface() void WaylandInterface::setDockExtraFlags(QQuickWindow &view) { - KWindowSystem::setType(view.winId(), NET::Dock); - KWindowSystem::setState(view.winId(), NET::SkipTaskbar | NET::SkipPager); + // KWindowSystem::setType(view.winId(), NET::Dock); + // KWindowSystem::setState(view.winId(), NET::SkipTaskbar | NET::SkipPager); KWindowSystem::setOnAllDesktops(view.winId(), true); KWindowSystem::setOnActivities(view.winId(), {"0"}); } @@ -201,28 +201,28 @@ bool WaylandInterface::isOnCurrentDesktop(WId wid) const WindowInfoWrap WaylandInterface::requestInfo(WId wid) const { - const KWindowInfo winfo{wid, NET::WMFrameExtents - | NET::WMWindowType - | NET::WMGeometry - | NET::WMState}; + /* const KWindowInfo winfo{wid, NET::WMFrameExtents + | NET::WMWindowType + | NET::WMGeometry + | NET::WMState};*/ WindowInfoWrap winfoWrap; - if (isValidWindow(winfo)) { - winfoWrap.setIsValid(true); - winfoWrap.setWid(wid); - winfoWrap.setIsActive(KWindowSystem::activeWindow() == wid); - winfoWrap.setIsMinimized(winfo.hasState(NET::Hidden)); - winfoWrap.setIsMaxVert(winfo.hasState(NET::MaxVert)); - winfoWrap.setIsMaxHoriz(winfo.hasState(NET::MaxHoriz)); - winfoWrap.setIsFullscreen(winfo.hasState(NET::FullScreen)); - winfoWrap.setIsShaded(winfo.hasState(NET::Shaded)); - winfoWrap.setGeometry(winfo.frameGeometry()); - } else if (m_desktopId == wid) { - winfoWrap.setIsValid(true); - winfoWrap.setIsPlasmaDesktop(true); - winfoWrap.setWid(wid); - } + /* if (isValidWindow(winfo)) { + winfoWrap.setIsValid(true); + winfoWrap.setWid(wid); + winfoWrap.setIsActive(KWindowSystem::activeWindow() == wid); + winfoWrap.setIsMinimized(winfo.hasState(NET::Hidden)); + winfoWrap.setIsMaxVert(winfo.hasState(NET::MaxVert)); + winfoWrap.setIsMaxHoriz(winfo.hasState(NET::MaxHoriz)); + winfoWrap.setIsFullscreen(winfo.hasState(NET::FullScreen)); + winfoWrap.setIsShaded(winfo.hasState(NET::Shaded)); + winfoWrap.setGeometry(winfo.frameGeometry()); + } else if (m_desktopId == wid) { + winfoWrap.setIsValid(true); + winfoWrap.setIsPlasmaDesktop(true); + winfoWrap.setWid(wid); + }*/ return winfoWrap; } @@ -230,46 +230,47 @@ WindowInfoWrap WaylandInterface::requestInfo(WId wid) const bool WaylandInterface::isValidWindow(const KWindowInfo &winfo) const { - constexpr auto types = NET::DockMask | NET::MenuMask | NET::SplashMask | NET::NormalMask; - auto winType = winfo.windowType(types); - - if (winType == -1) { - // Trying to get more types for verify if the window have any other type - winType = winfo.windowType(~types & NET::AllTypesMask); - - if (winType == -1) { - qWarning() << KWindowInfo(winfo.win(), 0, NET::WM2WindowClass).windowClassName() - << "doesn't have any WindowType, assuming as NET::Normal"; - return true; - } - } - - return !((winType & NET::Menu) || (winType & NET::Dock) || (winType & NET::Splash)); + /* constexpr auto types = NET::DockMask | NET::MenuMask | NET::SplashMask | NET::NormalMask; + auto winType = winfo.windowType(types); + + if (winType == -1) { + // Trying to get more types for verify if the window have any other type + winType = winfo.windowType(~types & NET::AllTypesMask); + + if (winType == -1) { + qWarning() << KWindowInfo(winfo.win(), 0, NET::WM2WindowClass).windowClassName() + << "doesn't have any WindowType, assuming as NET::Normal"; + return true; + } + }*/ + return true; + + //return !((winType & NET::Menu) || (winType & NET::Dock) || (winType & NET::Splash)); } void WaylandInterface::windowChangedProxy(WId wid, NET::Properties prop1, NET::Properties2 prop2) { //! if the dock changed is ignored - if (std::find(m_docks.cbegin(), m_docks.cend(), wid) != m_docks.cend()) - return; + /* if (std::find(m_docks.cbegin(), m_docks.cend(), wid) != m_docks.cend()) + return; - const auto winType = KWindowInfo(wid, NET::WMWindowType).windowType(NET::DesktopMask); + const auto winType = KWindowInfo(wid, NET::WMWindowType).windowType(NET::DesktopMask); - if (winType != -1 && (winType & NET::Desktop)) { - m_desktopId = wid; - emit windowChanged(wid); - return; - } + if (winType != -1 && (winType & NET::Desktop)) { + m_desktopId = wid; + emit windowChanged(wid); + return; + } - //! ignore when, eg: the user presses a key - if (prop1 == 0 && prop2 == NET::WM2UserTime) { - return; - } + //! ignore when, eg: the user presses a key + if (prop1 == 0 && prop2 == NET::WM2UserTime) { + return; + } - if (prop1 && !(prop1 & NET::WMState || prop1 & NET::WMGeometry || prop1 & NET::ActiveWindow)) - return; + if (prop1 && !(prop1 & NET::WMState || prop1 & NET::WMGeometry || prop1 & NET::ActiveWindow)) + return; - emit windowChanged(wid); + emit windowChanged(wid);*/ } }