From 2bc29f32ec087f8577ff1fd6bb031ea47b133057 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Tue, 22 Mar 2022 21:28:57 +0100 Subject: [PATCH] finally fixed XWayland popups --- src/Compositor.cpp | 2 +- src/Window.hpp | 1 + src/events/Windows.cpp | 3 +++ src/layout/DwindleLayout.cpp | 4 ++-- src/managers/XWaylandManager.cpp | 26 ++++++++++++++++++++++++-- src/managers/XWaylandManager.hpp | 1 + src/render/Renderer.cpp | 2 +- 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index e747e597..953ae1c8 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -321,7 +321,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface) { return; // Don't focus when already focused on this. // Unfocus last surface - if (m_pLastFocus) + if (m_pLastFocus && !wlr_surface_is_xwayland_surface(m_pLastFocus)) g_pXWaylandManager->activateSurface(m_pLastFocus, false); const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat); diff --git a/src/Window.hpp b/src/Window.hpp index ea0a3bd4..08e539cb 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -49,6 +49,7 @@ public: bool m_bMappedX11 = false; uint64_t m_iX11Type = 0; bool m_bIsModal = false; + bool m_bX11DoesntWantBorders = false; DYNLISTENER(activateX11); DYNLISTENER(configureX11); // diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index e353dc2f..af0867a1 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -24,6 +24,9 @@ void Events::listener_mapWindow(wl_listener* listener, void* data) { PWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace; PWINDOW->m_bIsMapped = true; + // checks if the window wants borders and sets the appriopriate flag + g_pXWaylandManager->checkBorders(PWINDOW); + const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(PWINDOW); if (!PWINDOWSURFACE) { diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 38589a3d..904c3f31 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -335,13 +335,13 @@ void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) { // check if it's on the correct monitor! Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f; - if (g_pCompositor->getMonitorFromVector(middlePoint)->ID != pWindow->m_iMonitorID) { + // TODO: detect a popup in a more consistent way. + if (g_pCompositor->getMonitorFromVector(middlePoint)->ID != pWindow->m_iMonitorID || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) { // if it's not, fall back to the center placement pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f); } else { // if it is, we respect where it wants to put itself. // most of these are popups - // TODO: detect a popup in a more consistent way. pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y); } } diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 30acf830..d17c1e5c 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -109,7 +109,9 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) { pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLBAR"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_UTILITY"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"]) - return true; + { + return true; + } if (pWindow->m_uSurface.xwayland->modal) { pWindow->m_bIsModal = true; @@ -117,7 +119,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) { } const auto SIZEHINTS = pWindow->m_uSurface.xwayland->size_hints; - if (SIZEHINTS && SIZEHINTS->min_width > 0 && SIZEHINTS->min_height > 0 && (SIZEHINTS->max_width == SIZEHINTS->min_width || SIZEHINTS->max_height == SIZEHINTS->min_height)) + if (SIZEHINTS && (pWindow->m_uSurface.xwayland->parent || ((SIZEHINTS->min_width == SIZEHINTS->max_width) && (SIZEHINTS->min_height == SIZEHINTS->max_height)))) return true; } else { const auto PSTATE = &pWindow->m_uSurface.xdg->toplevel->current; @@ -134,3 +136,23 @@ void CHyprXWaylandManager::moveXWaylandWindow(CWindow* pWindow, const Vector2D& wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.x, pWindow->m_vRealSize.y); } } + +void CHyprXWaylandManager::checkBorders(CWindow* pWindow) { + if (!pWindow->m_bIsX11) + return; + + for (size_t i = 0; i < pWindow->m_uSurface.xwayland->window_type_len; i++) { + if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_NOTIFICATION"] || + pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_COMBO"] || + pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] || + pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"]) { + + pWindow->m_bX11DoesntWantBorders = true; + return; + } + } + + if (pWindow->m_uSurface.xwayland->parent) { + pWindow->m_bX11DoesntWantBorders = true; + } +} \ No newline at end of file diff --git a/src/managers/XWaylandManager.hpp b/src/managers/XWaylandManager.hpp index f7456322..be7221d9 100644 --- a/src/managers/XWaylandManager.hpp +++ b/src/managers/XWaylandManager.hpp @@ -20,6 +20,7 @@ public: wlr_surface* surfaceAt(CWindow*, const Vector2D&, Vector2D&); bool shouldBeFloated(CWindow*); void moveXWaylandWindow(CWindow*, const Vector2D&); + void checkBorders(CWindow*); }; inline std::unique_ptr g_pXWaylandManager; \ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f3b08ff2..530aa0a9 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -61,7 +61,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, SWor void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) { // border - if (decorate) + if (decorate && !pWindow->m_bX11DoesntWantBorders) drawBorderForWindow(pWindow, pMonitor); SRenderData renderdata = {pMonitor->output, time, pWindow->m_vRealPosition.x, pWindow->m_vRealPosition.y};