diff --git a/src/Compositor.cpp b/src/Compositor.cpp index f1609620..4d3cfc85 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -60,7 +60,7 @@ CCompositor::CCompositor() { m_sWLRXCursorMgr = wlr_xcursor_manager_create(nullptr, 24); wlr_xcursor_manager_load(m_sWLRXCursorMgr, 1); - m_sWLRSeat = wlr_seat_create(m_sWLDisplay, "seat0"); + m_sSeat.seat = wlr_seat_create(m_sWLDisplay, "seat0"); m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend); @@ -73,6 +73,9 @@ CCompositor::CCompositor() { wlr_xdg_output_manager_v1_create(m_sWLDisplay, m_sWLROutputLayout); m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay); + + m_sWLRInhibitMgr = wlr_input_inhibit_manager_create(m_sWLDisplay); + m_sWLRKbShInhibitMgr = wlr_keyboard_shortcuts_inhibit_v1_create(m_sWLDisplay); } CCompositor::~CCompositor() { @@ -88,13 +91,15 @@ void CCompositor::initAllSignals() { wl_signal_add(&m_sWLRCursor->events.axis, &Events::listen_mouseAxis); wl_signal_add(&m_sWLRCursor->events.frame, &Events::listen_mouseFrame); wl_signal_add(&m_sWLRBackend->events.new_input, &Events::listen_newInput); - wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listen_requestMouse); - wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listen_requestSetSel); - wl_signal_add(&m_sWLRSeat->events.request_start_drag, &Events::listen_requestDrag); + wl_signal_add(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse); + wl_signal_add(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel); + wl_signal_add(&m_sSeat.seat->events.request_start_drag, &Events::listen_requestDrag); wl_signal_add(&m_sWLRLayerShell->events.new_surface, &Events::listen_newLayerSurface); wl_signal_add(&m_sWLROutputLayout->events.change, &Events::listen_change); wl_signal_add(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply); wl_signal_add(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest); + wl_signal_add(&m_sWLRInhibitMgr->events.activate, &Events::listen_InhibitActivate); + wl_signal_add(&m_sWLRInhibitMgr->events.deactivate, &Events::listen_InhibitDeactivate); } void CCompositor::startCompositor() { @@ -244,13 +249,13 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { // TODO: make an actual Z-system for (auto& w : m_lWindows) { wlr_box box = {w.m_vRealPosition.x, w.m_vRealPosition.y, w.m_vRealSize.x, w.m_vRealSize.y}; - if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w.m_bIsFloating && isWorkspaceVisible(w.m_iWorkspaceID)) + if (w.m_bIsFloating && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible(w.m_iWorkspaceID) && !w.m_bIsModal) return &w; } for (auto& w : m_lWindows) { wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y}; - if (wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace) + if (!w.m_bIsFloating && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace) return &w; } @@ -278,7 +283,6 @@ CWindow* CCompositor::windowFromCursor() { } CWindow* CCompositor::windowFloatingFromCursor() { - const auto PMONITOR = getMonitorFromCursor(); for (auto& w : m_lWindows) { wlr_box box = {w.m_vRealPosition.x, w.m_vRealPosition.y, w.m_vRealSize.x, w.m_vRealSize.y}; if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w.m_bIsFloating && isWorkspaceVisible(w.m_iWorkspaceID)) @@ -301,7 +305,7 @@ SMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) { void CCompositor::focusWindow(CWindow* pWindow) { if (!pWindow) { - wlr_seat_keyboard_notify_clear_focus(m_sWLRSeat); + wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat); return; } @@ -313,15 +317,15 @@ void CCompositor::focusWindow(CWindow* pWindow) { } void CCompositor::focusSurface(wlr_surface* pSurface) { - if (m_sWLRSeat->keyboard_state.focused_surface == pSurface) + if (m_sSeat.seat->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, pSurface, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); + const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat); + wlr_seat_keyboard_notify_enter(m_sSeat.seat, pSurface, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); m_pLastFocus = pSurface; @@ -457,4 +461,8 @@ void CCompositor::fixXWaylandWindowsOnWorkspace(const int& id) { g_pXWaylandManager->moveXWaylandWindow(&w, Vector2D(42069,42069)); } } +} + +bool CCompositor::doesSeatAcceptInput(wlr_surface* surface) { + return !m_sSeat.exclusiveClient || m_sSeat.exclusiveClient == wl_resource_get_client(surface->resource); } \ No newline at end of file diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 580e1ec4..748b894f 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -39,10 +39,11 @@ public: wlr_cursor* m_sWLRCursor; wlr_xcursor_manager* m_sWLRXCursorMgr; wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr; - wlr_seat* m_sWLRSeat; wlr_output_manager_v1* m_sWLROutputMgr; wlr_presentation* m_sWLRPresentation; wlr_scene* m_sWLRScene; + wlr_input_inhibit_manager* m_sWLRInhibitMgr; + wlr_keyboard_shortcuts_inhibit_manager_v1* m_sWLRKbShInhibitMgr; // ------------------------------------------------- // @@ -59,6 +60,8 @@ public: wlr_surface* m_pLastFocus = nullptr; SMonitor* m_pLastMonitor = nullptr; + + SSeat m_sSeat; // ------------------------------------------------- // @@ -87,6 +90,7 @@ public: CWindow* getFirstWindowOnWorkspace(const int&); void fixXWaylandWindowsOnWorkspace(const int&); CWindow* getFullscreenWindowOnWorkspace(const int&); + bool doesSeatAcceptInput(wlr_surface*); private: void initAllSignals(); diff --git a/src/Window.hpp b/src/Window.hpp index 9aed5904..bfa9a795 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -46,6 +46,7 @@ public: bool m_bIsX11 = false; bool m_bMappedX11 = false; uint64_t m_iX11Type = 0; + bool m_bIsModal = false; DYNLISTENER(activateX11); DYNLISTENER(configureX11); // diff --git a/src/events/Devices.cpp b/src/events/Devices.cpp index b9c54f57..846b9070 100644 --- a/src/events/Devices.cpp +++ b/src/events/Devices.cpp @@ -33,7 +33,7 @@ void Events::listener_keyboardMod(wl_listener* listener, void* data) { } void Events::listener_mouseFrame(wl_listener* listener, void* data) { - wlr_seat_pointer_notify_frame(g_pCompositor->m_sWLRSeat); + wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat); } void Events::listener_mouseMove(wl_listener* listener, void* data) { @@ -51,13 +51,13 @@ void Events::listener_mouseButton(wl_listener* listener, void* data) { void Events::listener_mouseAxis(wl_listener* listener, void* data) { const auto E = (wlr_event_pointer_axis*)data; - wlr_seat_pointer_notify_axis(g_pCompositor->m_sWLRSeat, E->time_msec, E->orientation, E->delta, E->delta_discrete, E->source); + wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, E->time_msec, E->orientation, E->delta, E->delta_discrete, E->source); } void Events::listener_requestMouse(wl_listener* listener, void* data) { const auto EVENT = (wlr_seat_pointer_request_set_cursor_event*)data; - if (EVENT->seat_client == g_pCompositor->m_sWLRSeat->pointer_state.focused_client) + if (EVENT->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, EVENT->surface, EVENT->hotspot_x, EVENT->hotspot_y); } @@ -79,5 +79,5 @@ void Events::listener_newInput(wl_listener* listener, void* data) { uint32_t capabilities = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD; - wlr_seat_set_capabilities(g_pCompositor->m_sWLRSeat, capabilities); + wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, capabilities); } \ No newline at end of file diff --git a/src/events/Events.hpp b/src/events/Events.hpp index ed727f7a..b7fac9d6 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -85,4 +85,8 @@ namespace Events { // Drag & Drop LISTENER(requestDrag); LISTENER(startDrag); + + // Inhibit + LISTENER(InhibitActivate); + LISTENER(InhibitDeactivate); }; \ No newline at end of file diff --git a/src/events/Misc.cpp b/src/events/Misc.cpp index f31ca3b9..545c4995 100644 --- a/src/events/Misc.cpp +++ b/src/events/Misc.cpp @@ -27,12 +27,12 @@ void Events::listener_outputMgrTest(wl_listener* listener, void* data) { void Events::listener_requestSetPrimarySel(wl_listener* listener, void* data) { const auto EVENT = (wlr_seat_request_set_primary_selection_event*)data; - wlr_seat_set_primary_selection(g_pCompositor->m_sWLRSeat, EVENT->source, EVENT->serial); + wlr_seat_set_primary_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial); } void Events::listener_requestSetSel(wl_listener* listener, void* data) { const auto EVENT = (wlr_seat_request_set_selection_event*)data; - wlr_seat_set_selection(g_pCompositor->m_sWLRSeat, EVENT->source, EVENT->serial); + wlr_seat_set_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial); } void Events::listener_readyXWayland(wl_listener* listener, void* data) { @@ -55,7 +55,7 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) { ATOM.second = reply->atom; } - wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sWLRSeat); + wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sSeat.seat); const auto XCURSOR = wlr_xcursor_manager_get_xcursor(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", 1); if (XCURSOR) { @@ -68,15 +68,28 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) { void Events::listener_requestDrag(wl_listener* listener, void* data) { const auto E = (wlr_seat_request_start_drag_event*)data; - if (!wlr_seat_validate_pointer_grab_serial(g_pCompositor->m_sWLRSeat, E->origin, E->serial)) { + if (!wlr_seat_validate_pointer_grab_serial(g_pCompositor->m_sSeat.seat, E->origin, E->serial)) { Debug::log(LOG, "Ignoring drag and drop request: serial mismatch."); wlr_data_source_destroy(E->drag->source); return; } - wlr_seat_start_pointer_drag(g_pCompositor->m_sWLRSeat, E->drag, E->serial); + wlr_seat_start_pointer_drag(g_pCompositor->m_sSeat.seat, E->drag, E->serial); } void Events::listener_startDrag(wl_listener* listener, void* data) { // TODO: draw the drag icon +} + +void Events::listener_InhibitActivate(wl_listener* listener, void* data) { + g_pCompositor->m_sSeat.exclusiveClient = g_pCompositor->m_sWLRInhibitMgr->active_client; + + Debug::log(LOG, "Activated exclusive for %x.", g_pCompositor->m_sSeat.exclusiveClient); +} + +void Events::listener_InhibitDeactivate(wl_listener* listener, void* data) { + g_pCompositor->m_sSeat.exclusiveClient = nullptr; + g_pInputManager->refocus(); + + Debug::log(LOG, "Deactivated exclusive."); } \ No newline at end of file diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 040d49da..9b2f7945 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -39,7 +39,8 @@ void Events::listener_mapWindow(wl_listener* listener, void* data) { else g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); - g_pCompositor->focusWindow(PWINDOW); + if (!PWINDOW->m_bIsModal) + g_pCompositor->focusWindow(PWINDOW); Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.x, PWINDOW->m_vRealPosition.y, PWINDOW->m_vRealSize.x, PWINDOW->m_vRealSize.y); } diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index c37bf5a5..791e69f2 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -99,4 +99,9 @@ struct SXDGPopup { bool operator==(const SXDGPopup& rhs) { return popup == rhs.popup; } +}; + +struct SSeat { + wlr_seat* seat = nullptr; + wl_client* exclusiveClient = nullptr; }; \ No newline at end of file diff --git a/src/includes.hpp b/src/includes.hpp index 593e363d..051d6daa 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -67,6 +67,8 @@ extern "C" { #include #include #include +#include +#include #include #include #include diff --git a/src/managers/InputManager.cpp b/src/managers/InputManager.cpp index d39767e0..c6bafd4e 100644 --- a/src/managers/InputManager.cpp +++ b/src/managers/InputManager.cpp @@ -46,10 +46,11 @@ void CInputManager::mouseMoveUnified(uint32_t time) { 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()); + const auto PWINDOWIDEAL = g_pCompositor->vectorToWindowIdeal(mouseCoords); + if (!foundSurface && PWINDOWIDEAL && !PWINDOWIDEAL->m_bIsModal) { + foundSurface = g_pXWaylandManager->getWindowSurface(PWINDOWIDEAL); if (foundSurface) - surfacePos = g_pCompositor->windowFromCursor()->m_vRealPosition; + surfacePos = PWINDOWIDEAL->m_vRealPosition; } // then surfaces below @@ -63,29 +64,29 @@ void CInputManager::mouseMoveUnified(uint32_t time) { 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); + wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat); return; } if (time) - wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sWLRSeat); + wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat); g_pCompositor->focusSurface(foundSurface); Vector2D surfaceLocal = Vector2D(g_pCompositor->m_sWLRCursor->x, g_pCompositor->m_sWLRCursor->y) - surfacePos; - 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); + wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); + wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y); g_pCompositor->m_pLastMonitor = g_pCompositor->getMonitorFromCursor(); g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal()); } void CInputManager::onMouseButton(wlr_event_pointer_button* e) { - wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sWLRSeat); + wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat); - const auto PKEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sWLRSeat); + const auto PKEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat); switch (e->state) { case WLR_BUTTON_PRESSED: @@ -105,7 +106,9 @@ void CInputManager::onMouseButton(wlr_event_pointer_button* e) { } // notify app if we didnt handle it - wlr_seat_pointer_notify_button(g_pCompositor->m_sWLRSeat, e->time_msec, e->button, e->state); + const auto PWINDOW = g_pCompositor->vectorToWindowIdeal(getMouseCoordsInternal()); + if (g_pCompositor->windowValidMapped(PWINDOW) && g_pCompositor->doesSeatAcceptInput(g_pXWaylandManager->getWindowSurface(PWINDOW))) + wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, e->time_msec, e->button, e->state); } Vector2D CInputManager::getMouseCoordsInternal() { @@ -133,7 +136,7 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) { wl_signal_add(&keyboard->keyboard->events.key, &PNEWKEYBOARD->listen_keyboardKey); wl_signal_add(&keyboard->events.destroy, &PNEWKEYBOARD->listen_keyboardDestroy); - wlr_seat_set_keyboard(g_pCompositor->m_sWLRSeat, keyboard); + wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard); Debug::log(LOG, "New keyboard created, pointers Hypr: %x and WLR: %x", PNEWKEYBOARD, keyboard); } @@ -174,7 +177,7 @@ void CInputManager::onKeyboardKey(wlr_event_keyboard_key* e, SKeyboard* pKeyboar const auto MODS = wlr_keyboard_get_modifiers(pKeyboard->keyboard->keyboard); - wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sWLRSeat); + wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat); bool found = false; if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) { @@ -185,14 +188,14 @@ void CInputManager::onKeyboardKey(wlr_event_keyboard_key* e, SKeyboard* pKeyboar } if (!found) { - wlr_seat_set_keyboard(g_pCompositor->m_sWLRSeat, pKeyboard->keyboard); - wlr_seat_keyboard_notify_key(g_pCompositor->m_sWLRSeat, e->time_msec, e->keycode, e->state); + wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard); + wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state); } } void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) { - wlr_seat_set_keyboard(g_pCompositor->m_sWLRSeat, pKeyboard->keyboard); - wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sWLRSeat, &pKeyboard->keyboard->keyboard->modifiers); + wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard); + wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &pKeyboard->keyboard->keyboard->modifiers); } void CInputManager::refocus() { diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 4f8a15b7..30acf830 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -109,10 +109,12 @@ 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) + if (pWindow->m_uSurface.xwayland->modal) { + pWindow->m_bIsModal = true; return true; + } 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))