From f8a731b10b653a6450fe7c8beea48db9373b32f8 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sun, 20 Mar 2022 14:36:55 +0100 Subject: [PATCH] focus to layers --- src/Compositor.cpp | 47 ++++++++++++++++++++++++++------- src/Compositor.hpp | 5 +++- src/events/Events.cpp | 11 ++++++++ src/layout/DwindleLayout.cpp | 2 +- src/managers/InputManager.cpp | 35 +++++++++++++++++++----- src/managers/KeybindManager.cpp | 6 ++--- src/render/Renderer.cpp | 2 +- 7 files changed, 85 insertions(+), 23 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 9636be9d..9e414a53 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -282,21 +282,25 @@ void CCompositor::focusWindow(CWindow* pWindow) { const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(pWindow); - if (m_sWLRSeat->keyboard_state.focused_surface == PWINDOWSURFACE) - return; // Don't focus when already focused on this. + focusSurface(PWINDOWSURFACE); - // Unfocus last window - if (m_pLastFocus && windowValidMapped(m_pLastFocus)) - g_pXWaylandManager->activateSurface(g_pXWaylandManager->getWindowSurface(m_pLastFocus), false); + Debug::log(LOG, "Set keyboard focus to %x, with name: %s", pWindow, pWindow->m_szTitle.c_str()); +} + +void CCompositor::focusSurface(wlr_surface* pSurface) { + if (m_sWLRSeat->keyboard_state.focused_surface == pSurface) + return; // Don't focus when already focused on this. + + // Unfocus last surface + if (m_pLastFocus) + g_pXWaylandManager->activateSurface(m_pLastFocus, false); const auto KEYBOARD = wlr_seat_get_keyboard(m_sWLRSeat); - wlr_seat_keyboard_notify_enter(m_sWLRSeat, PWINDOWSURFACE, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); + wlr_seat_keyboard_notify_enter(m_sWLRSeat, pSurface, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); - g_pXWaylandManager->activateSurface(PWINDOWSURFACE, true); - - m_pLastFocus = pWindow; + m_pLastFocus = pSurface; - Debug::log(LOG, "Set keyboard %x focus to %x, with name: %s", KEYBOARD, pWindow, pWindow->m_szTitle.c_str()); + g_pXWaylandManager->activateSurface(pSurface, true); } bool CCompositor::windowValidMapped(CWindow* pWindow) { @@ -332,5 +336,28 @@ CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) { return p.parentWindow; } + return nullptr; +} + +wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::list* layerSurfaces, Vector2D* sCoords) { + for (auto& l : *layerSurfaces) { + if (!l->layerSurface->mapped) + continue; + + const auto SURFACEAT = wlr_layer_surface_v1_surface_at(l->layerSurface, pos.x - l->geometry.x, pos.y - l->geometry.y, &sCoords->x, &sCoords->y); + + if (SURFACEAT) + return SURFACEAT; + } + + return nullptr; +} + +CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) { + for (auto& w : m_lWindows) { + if (g_pXWaylandManager->getWindowSurface(&w) == pSurface) + return &w; + } + return nullptr; } \ No newline at end of file diff --git a/src/Compositor.hpp b/src/Compositor.hpp index c9d1c528..b1cb1370 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -53,7 +53,7 @@ public: void startCompositor(); - CWindow* m_pLastFocus = nullptr; + wlr_surface* m_pLastFocus = nullptr; SMonitor* m_pLastMonitor = nullptr; // ------------------------------------------------- // @@ -63,15 +63,18 @@ public: SMonitor* getMonitorFromVector(const Vector2D&); void removeWindowFromVectorSafe(CWindow*); void focusWindow(CWindow*); + void focusSurface(wlr_surface*); bool windowExists(CWindow*); bool windowValidMapped(CWindow*); CWindow* vectorToWindow(const Vector2D&); CWindow* vectorToWindowIdeal(const Vector2D&); + wlr_surface* vectorToLayerSurface(const Vector2D&, std::list*, Vector2D*); CWindow* windowFromCursor(); CWindow* windowFloatingFromCursor(); SMonitor* getMonitorFromOutput(wlr_output*); SLayerSurface* getLayerForPopup(SLayerPopup*); CWindow* getWindowForPopup(wlr_xdg_popup*); + CWindow* getWindowFromSurface(wlr_surface*); private: void initAllSignals(); diff --git a/src/events/Events.cpp b/src/events/Events.cpp index 8191f295..4367eb16 100644 --- a/src/events/Events.cpp +++ b/src/events/Events.cpp @@ -183,6 +183,8 @@ void Events::listener_destroyLayerSurface(wl_listener* listener, void* data) { if (layersurface->layerSurface->mapped) layersurface->layerSurface->mapped = 0; + if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) + g_pCompositor->m_pLastFocus = nullptr; wl_list_remove(&layersurface->listen_destroyLayerSurface.link); wl_list_remove(&layersurface->listen_mapLayerSurface.link); @@ -212,6 +214,9 @@ void Events::listener_unmapLayerSurface(wl_listener* listener, void* data) { if (layersurface->layerSurface->mapped) layersurface->layerSurface->mapped = 0; + if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) + g_pCompositor->m_pLastFocus = nullptr; + Debug::log(LOG, "LayerSurface %x unmapped", layersurface); } @@ -477,6 +482,9 @@ void Events::listener_mapWindow(wl_listener* listener, void* data) { void Events::listener_unmapWindow(wl_listener* listener, void* data) { CWindow* PWINDOW = wl_container_of(listener, PWINDOW, listen_unmapWindow); + if (g_pXWaylandManager->getWindowSurface(PWINDOW) == g_pCompositor->m_pLastFocus) + g_pCompositor->m_pLastFocus = nullptr; + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW); g_pCompositor->removeWindowFromVectorSafe(PWINDOW); @@ -493,6 +501,9 @@ void Events::listener_commitWindow(wl_listener* listener, void* data) { void Events::listener_destroyWindow(wl_listener* listener, void* data) { CWindow* PWINDOW = wl_container_of(listener, PWINDOW, listen_destroyWindow); + if (g_pXWaylandManager->getWindowSurface(PWINDOW) == g_pCompositor->m_pLastFocus) + g_pCompositor->m_pLastFocus = nullptr; + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW); g_pCompositor->removeWindowFromVectorSafe(PWINDOW); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 9f97cece..b932c222 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -143,7 +143,7 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { } // If it's not, get the last node. - const auto PLASTFOCUS = getNodeFromWindow(g_pCompositor->m_pLastFocus); + const auto PLASTFOCUS = getNodeFromWindow(g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus)); SDwindleNodeData* OPENINGON = PLASTFOCUS; if (PLASTFOCUS) { if (PLASTFOCUS->monitorID != PNODE->monitorID) { diff --git a/src/managers/InputManager.cpp b/src/managers/InputManager.cpp index cc7d302c..f05c0ba5 100644 --- a/src/managers/InputManager.cpp +++ b/src/managers/InputManager.cpp @@ -20,9 +20,32 @@ void CInputManager::onMouseWarp(wlr_event_pointer_motion_absolute* e) { void CInputManager::mouseMoveUnified(uint32_t time) { - const auto PWINDOW = g_pCompositor->windowFromCursor(); + // first top layers + wlr_surface* foundSurface = nullptr; + Vector2D mouseCoords = getMouseCoordsInternal(); + const auto PMONITOR = g_pCompositor->getMonitorFromCursor(); + Vector2D surfacePos; - if (!PWINDOW) { + foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfacePos); + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfacePos); + + // then windows + if (!foundSurface && g_pCompositor->vectorToWindowIdeal(mouseCoords)) { + foundSurface = g_pXWaylandManager->getWindowSurface(g_pCompositor->windowFromCursor()); + if (foundSurface) + surfacePos = g_pCompositor->windowFromCursor()->m_vRealPosition; + } + + // then surfaces below + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &surfacePos); + + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfacePos); + + + if (!foundSurface) { wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor); wlr_seat_pointer_clear_focus(g_pCompositor->m_sWLRSeat); @@ -33,11 +56,11 @@ void CInputManager::mouseMoveUnified(uint32_t time) { if (time) wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sWLRSeat); - g_pCompositor->focusWindow(PWINDOW); + g_pCompositor->focusSurface(foundSurface); - Vector2D surfaceLocal = Vector2D(g_pCompositor->m_sWLRCursor->x, g_pCompositor->m_sWLRCursor->y) - PWINDOW->m_vEffectivePosition; + Vector2D surfaceLocal = Vector2D(g_pCompositor->m_sWLRCursor->x, g_pCompositor->m_sWLRCursor->y) - surfacePos; - wlr_seat_pointer_notify_enter(g_pCompositor->m_sWLRSeat, g_pXWaylandManager->getWindowSurface(PWINDOW), surfaceLocal.x, surfaceLocal.y); + wlr_seat_pointer_notify_enter(g_pCompositor->m_sWLRSeat, foundSurface, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_motion(g_pCompositor->m_sWLRSeat, time, surfaceLocal.x, surfaceLocal.y); g_pCompositor->m_pLastMonitor = g_pCompositor->getMonitorFromCursor(); @@ -63,8 +86,6 @@ void CInputManager::onMouseButton(wlr_event_pointer_button* e) { } g_pCompositor->focusWindow(g_pCompositor->vectorToWindowIdeal(Vector2D(g_pCompositor->m_sWLRCursor->x, g_pCompositor->m_sWLRCursor->y))); - if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastFocus)) - Debug::log(LOG, "Clicked, window with focus now: %x (window xy: %f, %f, cursor xy: %f %f)", g_pCompositor->m_pLastFocus, g_pCompositor->m_pLastFocus->m_vRealPosition.x, g_pCompositor->m_pLastFocus->m_vRealPosition.y, g_pCompositor->m_sWLRCursor->x, g_pCompositor->m_sWLRCursor->y); // notify app if we didnt handle it wlr_seat_pointer_notify_button(g_pCompositor->m_sWLRSeat, e->time_msec, e->button, e->state); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 8edad6ad..35f2269d 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -63,8 +63,8 @@ void CKeybindManager::spawn(std::string args) { } void CKeybindManager::killActive(std::string args) { - if (g_pCompositor->m_pLastFocus && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastFocus)) - g_pXWaylandManager->sendCloseWindow(g_pCompositor->m_pLastFocus); + if (g_pCompositor->m_pLastFocus && g_pCompositor->windowValidMapped(g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus))) + g_pXWaylandManager->sendCloseWindow(g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus)); g_pCompositor->focusWindow(g_pCompositor->windowFromCursor()); } @@ -74,7 +74,7 @@ void CKeybindManager::clearKeybinds() { } void CKeybindManager::toggleActiveFloating(std::string args) { - const auto ACTIVEWINDOW = g_pCompositor->m_pLastFocus; + const auto ACTIVEWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus); if (g_pCompositor->windowValidMapped(ACTIVEWINDOW)) { ACTIVEWINDOW->m_bIsFloating = !ACTIVEWINDOW->m_bIsFloating; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 17ff9494..2f772e71 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -213,7 +213,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) { void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor) { const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); - const auto BORDERCOL = pWindow == g_pCompositor->m_pLastFocus ? g_pConfigManager->getInt("general:col.active_border") : g_pConfigManager->getInt("general:col.inactive_border"); + const auto BORDERCOL = pWindow == g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus) ? g_pConfigManager->getInt("general:col.active_border") : g_pConfigManager->getInt("general:col.inactive_border"); const float BORDERWLRCOL[4] = {RED(BORDERCOL), GREEN(BORDERCOL), BLUE(BORDERCOL), ALPHA(BORDERCOL)};