diff options
author | Vaxry <[email protected]> | 2024-02-14 23:08:03 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2024-02-14 23:08:03 +0000 |
commit | 3a6451b6026a5f38987e61ee07b442910b5432f5 (patch) | |
tree | 20cd2a725aac2d600c6a7b1b1cf29d3c622e22f3 | |
parent | 7af2e270fda4f20e3b4687ec07cbc149bb220930 (diff) | |
parent | 9c3f3b00183c9bcca528d1c74fa29eed0bd747fa (diff) | |
download | Hyprland-3a6451b6026a5f38987e61ee07b442910b5432f5.tar.gz Hyprland-3a6451b6026a5f38987e61ee07b442910b5432f5.zip |
Merge branch 'main' into hyprlang-migration
-rw-r--r-- | assets/wall1.png | bin | 5690948 -> 6144371 bytes | |||
-rw-r--r-- | example/hyprland.conf | 2 | ||||
-rw-r--r-- | flake.lock | 12 | ||||
-rw-r--r-- | hyprctl/main.cpp | 47 | ||||
-rw-r--r-- | nix/overlays.nix | 6 | ||||
-rw-r--r-- | src/Compositor.cpp | 30 | ||||
-rw-r--r-- | src/Window.hpp | 19 | ||||
-rw-r--r-- | src/config/ConfigManager.cpp | 10 | ||||
-rw-r--r-- | src/config/defaultConfig.hpp | 4 | ||||
-rw-r--r-- | src/debug/HyprCtl.cpp | 15 | ||||
-rw-r--r-- | src/debug/HyprNotificationOverlay.cpp | 4 | ||||
-rw-r--r-- | src/debug/HyprNotificationOverlay.hpp | 1 | ||||
-rw-r--r-- | src/events/Monitors.cpp | 16 | ||||
-rw-r--r-- | src/events/Windows.cpp | 44 | ||||
-rw-r--r-- | src/helpers/Monitor.hpp | 55 | ||||
-rw-r--r-- | src/layout/DwindleLayout.cpp | 31 | ||||
-rw-r--r-- | src/layout/DwindleLayout.hpp | 1 | ||||
-rw-r--r-- | src/layout/IHyprLayout.cpp | 4 | ||||
-rw-r--r-- | src/managers/KeybindManager.cpp | 16 | ||||
-rw-r--r-- | src/managers/KeybindManager.hpp | 1 | ||||
-rw-r--r-- | src/managers/input/InputManager.cpp | 15 | ||||
-rw-r--r-- | src/render/Renderer.cpp | 125 |
22 files changed, 261 insertions, 197 deletions
diff --git a/assets/wall1.png b/assets/wall1.png Binary files differindex ad2b5678..53e4c90d 100644 --- a/assets/wall1.png +++ b/assets/wall1.png diff --git a/example/hyprland.conf b/example/hyprland.conf index 5d5441e9..75ff0abe 100644 --- a/example/hyprland.conf +++ b/example/hyprland.conf @@ -126,7 +126,7 @@ device:epic-mouse-v1 { # Example windowrule v2 # windowrulev2 = float,class:^(kitty)$,title:^(kitty)$ # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more -windowrulev2 = nomaximizerequest, class:.* # You'll probably like this. +windowrulev2 = suppressevent maximize, class:.* # You'll probably like this. # See https://wiki.hyprland.org/Configuring/Keywords/ for more @@ -66,11 +66,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1706191920, - "narHash": "sha256-eLihrZAPZX0R6RyM5fYAWeKVNuQPYjAkCUBr+JNvtdE=", + "lastModified": 1707546158, + "narHash": "sha256-nYYJTpzfPMDxI8mzhQsYjIUX+grorqjKEU9Np6Xwy/0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ae5c332cbb5827f6b1f02572496b141021de335f", + "rev": "d934204a0f8d9198e1e4515dd6fec76a139c87f0", "type": "github" }, "original": { @@ -138,11 +138,11 @@ ] }, "locked": { - "lastModified": 1706145785, - "narHash": "sha256-j9MP4fv2U/vdRKAXXc2gyMTmYwVnHP6kHx1/y6jprrU=", + "lastModified": 1706521509, + "narHash": "sha256-AInZ50acOJ3wzUwGzNr1TmxGTMx+8j6oSTzz4E7Vbp8=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "5a592647587cd20b9692a347df6939b6d371b3bb", + "rev": "c06fd88b3da492b8f9067be021b9184f7012b5a8", "type": "github" }, "original": { diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index 281a74ac..b1d89a8a 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -371,44 +371,8 @@ int main(int argc, char** argv) { if (fullRequest.contains("/--batch")) batchRequest(fullRequest); - else if (fullRequest.contains("/monitors")) - request(fullRequest); - else if (fullRequest.contains("/clients")) - request(fullRequest); - else if (fullRequest.contains("/workspaces")) - request(fullRequest); - else if (fullRequest.contains("/activeworkspace")) - request(fullRequest); - else if (fullRequest.contains("/workspacerules")) - request(fullRequest); - else if (fullRequest.contains("/activewindow")) - request(fullRequest); - else if (fullRequest.contains("/layers")) - request(fullRequest); - else if (fullRequest.contains("/version")) - request(fullRequest); - else if (fullRequest.contains("/kill")) - request(fullRequest); - else if (fullRequest.contains("/systeminfo")) - request(fullRequest); - else if (fullRequest.contains("/splash")) - request(fullRequest); - else if (fullRequest.contains("/devices")) - request(fullRequest); - else if (fullRequest.contains("/reload")) - request(fullRequest); - else if (fullRequest.contains("/getoption")) - request(fullRequest); - else if (fullRequest.contains("/binds")) - request(fullRequest); - else if (fullRequest.contains("/cursorpos")) - request(fullRequest); - else if (fullRequest.contains("/animations")) - request(fullRequest); - else if (fullRequest.contains("/globalshortcuts")) - request(fullRequest); - else if (fullRequest.contains("/rollinglog")) - request(fullRequest); + else if (fullRequest.contains("/hyprpaper")) + requestHyprpaper(fullRequest); else if (fullRequest.contains("/switchxkblayout")) request(fullRequest, 2); else if (fullRequest.contains("/seterror")) @@ -429,15 +393,10 @@ int main(int argc, char** argv) { request(fullRequest, 2); else if (fullRequest.contains("/decorations")) request(fullRequest, 1); - else if (fullRequest.contains("/hyprpaper")) - requestHyprpaper(fullRequest); - else if (fullRequest.contains("/layouts")) - request(fullRequest); else if (fullRequest.contains("/--help")) printf("%s", USAGE.c_str()); else { - printf("%s\n", USAGE.c_str()); - return 1; + request(fullRequest); } printf("\n"); diff --git a/nix/overlays.nix b/nix/overlays.nix index 3eedd84c..0a84d93e 100644 --- a/nix/overlays.nix +++ b/nix/overlays.nix @@ -32,9 +32,9 @@ in { hyprland = final.callPackage ./default.nix { stdenv = final.gcc13Stdenv; version = "${props.version}+date=${date}_${self.shortRev or "dirty"}"; - wlroots = prev.wlroots-hyprland; commit = self.rev or ""; - inherit (final) udis86 hyprland-protocols; + wlroots = final.wlroots-hyprland; # explicit override until decided on breaking change of the name + udis86 = final.udis86-hyprland; # explicit override until decided on breaking change of the name inherit date; }; hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;}; @@ -62,7 +62,7 @@ in { ]; udis86 = final: prev: { - udis86 = final.callPackage ./udis86.nix {}; + udis86-hyprland = final.callPackage ./udis86.nix {}; }; # Patched version of wlroots for Hyprland. diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 82bc6209..a3ce5609 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -710,7 +710,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert for (auto& w : m_vWindows | std::views::reverse) { const auto BB = w->getWindowBoxUnified(properties); CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; - if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_bNoFocus && w.get() != pIgnoreWindow) { + if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + w.get() != pIgnoreWindow) { if (box.containsPoint({m_sWLRCursor->x, m_sWLRCursor->y})) return w.get(); @@ -732,7 +733,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert const auto BB = w->getWindowBoxUnified(properties); CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; - if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_bNoFocus && w.get() != pIgnoreWindow) { + if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + w.get() != pIgnoreWindow) { // OR windows should add focus to parent if (w->m_bX11ShouldntFocus && w->m_iX11Type != 2) continue; @@ -770,8 +772,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert if (special != isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_bNoFocus && - w.get() != pIgnoreWindow) { + if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && + !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow) { if (w->hasPopupAt(pos)) return w.get(); } @@ -782,8 +784,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert continue; CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_vPosition, w->m_vSize}; - if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_bNoFocus && - w.get() != pIgnoreWindow) + if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && + !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow) return w.get(); } @@ -928,7 +930,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { return; } - if (pWindow->m_bNoFocus) { + if (pWindow->m_sAdditionalConfigData.noFocus) { Debug::log(LOG, "Ignoring focus to nofocus window!"); return; } @@ -1646,7 +1648,7 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1654,7 +1656,7 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1675,7 +1677,7 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1683,7 +1685,7 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -2028,7 +2030,11 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) updateFullscreenFadeOnWorkspace(PWORKSPACEB); updateFullscreenFadeOnWorkspace(PWORKSPACEA); - g_pInputManager->sendMotionEventsToFocused(); + if (pMonitorA->ID == g_pCompositor->m_pLastMonitor->ID || pMonitorB->ID == g_pCompositor->m_pLastMonitor->ID) { + const auto LASTWIN = pMonitorA->ID == g_pCompositor->m_pLastMonitor->ID ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow(); + g_pCompositor->focusWindow(LASTWIN ? LASTWIN : + (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING))); + } // event g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName}); diff --git a/src/Window.hpp b/src/Window.hpp index b0689b61..38eb857c 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -37,7 +37,15 @@ enum eGetWindowProperties { FULL_EXTENTS = 1 << 2, FLOATING_ONLY = 1 << 3, ALLOW_FLOATING = 1 << 4, - USE_PROP_TILED = 1 << 5 + USE_PROP_TILED = 1 << 5, +}; + +enum eSuppressEvents { + SUPPRESS_NONE = 0, + SUPPRESS_FULLSCREEN = 1 << 0, + SUPPRESS_MAXIMIZE = 1 << 1, + SUPPRESS_ACTIVATE = 1 << 2, + SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3, }; class IWindowTransformer; @@ -143,6 +151,7 @@ struct SWindowAdditionalConfigData { CWindowOverridableVar<bool> forceNoBorder = false; CWindowOverridableVar<bool> forceNoShadow = false; CWindowOverridableVar<bool> forceNoDim = false; + CWindowOverridableVar<bool> noFocus = false; CWindowOverridableVar<bool> windowDanceCompat = false; CWindowOverridableVar<bool> noMaxSize = false; CWindowOverridableVar<bool> dimAround = false; @@ -260,13 +269,13 @@ class CWindow { // // For nofocus - bool m_bNoFocus = false; bool m_bNoInitialFocus = false; // Fullscreen and Maximize - bool m_bWantsInitialFullscreen = false; - bool m_bNoFullscreenRequest = false; - bool m_bNoMaximizeRequest = false; + bool m_bWantsInitialFullscreen = false; + + // bitfield eSuppressEvents + uint64_t m_eSuppressedEvents = SUPPRESS_NONE; SSurfaceTreeNode* m_pSurfaceTree = nullptr; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index da479ac6..7888df36 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1812,11 +1812,11 @@ std::optional<std::string> CConfigManager::handleUnbind(const std::string& comma bool windowRuleValid(const std::string& RULE) { return RULE == "float" || RULE == "tile" || RULE.starts_with("opacity") || RULE.starts_with("move") || RULE.starts_with("size") || RULE.starts_with("minsize") || RULE.starts_with("maxsize") || RULE.starts_with("pseudo") || RULE.starts_with("monitor") || RULE.starts_with("idleinhibit") || RULE == "nofocus" || RULE == "noblur" || - RULE == "noshadow" || RULE == "nodim" || RULE == "noborder" || RULE == "opaque" || RULE == "forceinput" || RULE == "fullscreen" || RULE == "nofullscreenrequest" || - RULE == "nomaximizerequest" || RULE == "fakefullscreen" || RULE == "nomaxsize" || RULE == "pin" || RULE == "noanim" || RULE == "dimaround" || RULE == "windowdance" || - RULE == "maximize" || RULE == "keepaspectratio" || RULE.starts_with("animation") || RULE.starts_with("rounding") || RULE.starts_with("workspace") || - RULE.starts_with("bordercolor") || RULE == "forcergbx" || RULE == "noinitialfocus" || RULE == "stayfocused" || RULE.starts_with("bordersize") || RULE.starts_with("xray") || - RULE.starts_with("center") || RULE.starts_with("group") || RULE == "immediate" || RULE == "nearestneighbor"; + RULE == "noshadow" || RULE == "nodim" || RULE == "noborder" || RULE == "opaque" || RULE == "forceinput" || RULE == "fullscreen" || RULE == "fakefullscreen" || + RULE == "nomaxsize" || RULE == "pin" || RULE == "noanim" || RULE == "dimaround" || RULE == "windowdance" || RULE == "maximize" || RULE == "keepaspectratio" || + RULE.starts_with("animation") || RULE.starts_with("rounding") || RULE.starts_with("workspace") || RULE.starts_with("bordercolor") || RULE == "forcergbx" || + RULE == "noinitialfocus" || RULE == "stayfocused" || RULE.starts_with("bordersize") || RULE.starts_with("xray") || RULE.starts_with("center") || + RULE.starts_with("group") || RULE == "immediate" || RULE == "nearestneighbor" || RULE.starts_with("suppressevent"); } bool layerRuleValid(const std::string& RULE) { diff --git a/src/config/defaultConfig.hpp b/src/config/defaultConfig.hpp index ac889241..95e98e4f 100644 --- a/src/config/defaultConfig.hpp +++ b/src/config/defaultConfig.hpp @@ -51,7 +51,7 @@ input { natural_scroll = no } - sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + sensitivity = 0 # -1.0 to 1.0, 0 means no modification. } general { @@ -133,7 +133,7 @@ device:epic-mouse-v1 { # Example windowrule v2 # windowrulev2 = float,class:^(kitty)$,title:^(kitty)$ # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more -windowrulev2 = nomaximizerequest, class:.* # You'll probably like this. +windowrulev2 = suppressevent maximize, class:.* # You'll probably like this. # See https://wiki.hyprland.org/Configuring/Keywords/ for more diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 56dfd283..f2584ad0 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -965,7 +965,7 @@ std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) { nextItem(); - while (curitem != "") { + while (curitem != "" || request != "") { reply += g_pHyprCtl->getReply(curitem); nextItem(); @@ -1087,7 +1087,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { if (vars.size() < 4) return "not enough args"; - const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); + const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; + const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); if (!PWINDOW) return "window not found"; @@ -1095,6 +1096,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { const auto PROP = vars[2]; const auto VAL = vars[3]; + auto noFocus = PWINDOW->m_sAdditionalConfigData.noFocus; + bool lock = false; if (vars.size() > 4) { @@ -1124,6 +1127,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { PWINDOW->m_sAdditionalConfigData.forceNoShadow.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "forcenodim") { PWINDOW->m_sAdditionalConfigData.forceNoDim.forceSetIgnoreLocked(configStringToInt(VAL), lock); + } else if (PROP == "nofocus") { + PWINDOW->m_sAdditionalConfigData.noFocus.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "windowdancecompat") { PWINDOW->m_sAdditionalConfigData.windowDanceCompat.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "nomaxsize") { @@ -1159,6 +1164,12 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { g_pCompositor->updateAllWindowsAnimatedDecorationValues(); + if (!(PWINDOW->m_sAdditionalConfigData.noFocus.toUnderlying() == noFocus.toUnderlying())) { + g_pCompositor->focusWindow(nullptr); + g_pCompositor->focusWindow(PWINDOW); + g_pCompositor->focusWindow(PLASTWINDOW); + } + for (auto& m : g_pCompositor->m_vMonitors) g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID); diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index 12f7a575..2968134b 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -226,4 +226,8 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) { CBox pMonBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y}; g_pHyprOpenGL->renderTexture(m_tTexture, &pMonBox, 1.f); +} + +bool CHyprNotificationOverlay::hasAny() { + return !m_dNotifications.empty(); }
\ No newline at end of file diff --git a/src/debug/HyprNotificationOverlay.hpp b/src/debug/HyprNotificationOverlay.hpp index 84e61f80..7a883f15 100644 --- a/src/debug/HyprNotificationOverlay.hpp +++ b/src/debug/HyprNotificationOverlay.hpp @@ -41,6 +41,7 @@ class CHyprNotificationOverlay { void draw(CMonitor* pMonitor); void addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon = ICON_NONE); + bool hasAny(); private: CBox drawNotifications(CMonitor* pMonitor); diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 14d617fe..01ea24f8 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -209,10 +209,20 @@ void Events::listener_monitorDestroy(void* owner, void* data) { } void Events::listener_monitorStateRequest(void* owner, void* data) { - //const auto PMONITOR = (CMonitor*)owner; - //const auto E = (wlr_output_event_request_state*)data; + const auto PMONITOR = (CMonitor*)owner; + const auto E = (wlr_output_event_request_state*)data; + + if (!PMONITOR->createdByUser) + return; + + const auto SIZE = E->state->mode ? Vector2D{E->state->mode->width, E->state->mode->height} : Vector2D{E->state->custom_mode.width, E->state->custom_mode.height}; + + PMONITOR->forceSize = SIZE; + + SMonitorRule rule = PMONITOR->activeMonitorRule; + rule.resolution = SIZE; - // TODO: maybe don't ignore? + g_pHyprRenderer->applyMonitorRule(PMONITOR, &rule); } void Events::listener_monitorDamage(void* owner, void* data) { diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index f78bf199..b5072295 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -173,13 +173,23 @@ void Events::listener_mapWindow(void* owner, void* data) { } else if (r.szRule.starts_with("pseudo")) { PWINDOW->m_bIsPseudotiled = true; } else if (r.szRule.starts_with("nofocus")) { - PWINDOW->m_bNoFocus = true; + PWINDOW->m_sAdditionalConfigData.noFocus = true; } else if (r.szRule.starts_with("noinitialfocus")) { PWINDOW->m_bNoInitialFocus = true; - } else if (r.szRule.starts_with("nofullscreenrequest")) { - PWINDOW->m_bNoFullscreenRequest = true; - } else if (r.szRule.starts_with("nomaximizerequest")) { - PWINDOW->m_bNoMaximizeRequest = true; + } else if (r.szRule.starts_with("suppressevent")) { + CVarList vars(r.szRule, 0, 's', true); + for (size_t i = 1; i < vars.size(); ++i) { + if (vars[i] == "fullscreen") + PWINDOW->m_eSuppressedEvents |= SUPPRESS_FULLSCREEN; + else if (vars[i] == "maximize") + PWINDOW->m_eSuppressedEvents |= SUPPRESS_MAXIMIZE; + else if (vars[i] == "activate") + PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE; + else if (vars[i] == "activatefocus") + PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE_FOCUSONLY; + else + Debug::log(ERR, "Error while parsing suppressevent windowrule: unknown event type {}", vars[i]); + } } else if (r.szRule == "fullscreen") { requestsFullscreen = true; overridingNoFullscreen = true; @@ -443,9 +453,9 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow; if (PWINDOW->m_sAdditionalConfigData.forceAllowsInput) { - PWINDOW->m_bNoFocus = false; - PWINDOW->m_bNoInitialFocus = false; - PWINDOW->m_bX11ShouldntFocus = false; + PWINDOW->m_sAdditionalConfigData.noFocus = false; + PWINDOW->m_bNoInitialFocus = false; + PWINDOW->m_bX11ShouldntFocus = false; } // check LS focus grab @@ -464,7 +474,7 @@ void Events::listener_mapWindow(void* owner, void* data) { requestsFullscreen = true; } - if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && + if (!PWINDOW->m_sAdditionalConfigData.noFocus && !PWINDOW->m_bNoInitialFocus && (PWINDOW->m_iX11Type != 2 || (PWINDOW->m_bIsX11 && wlr_xwayland_or_surface_wants_focus(PWINDOW->m_uSurface.xwayland))) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW)) { g_pCompositor->focusWindow(PWINDOW); @@ -504,8 +514,8 @@ void Events::listener_mapWindow(void* owner, void* data) { "XWayland Window Late"); } - if ((requestsFullscreen && (!PWINDOW->m_bNoFullscreenRequest || overridingNoFullscreen)) || (requestsMaximize && (!PWINDOW->m_bNoMaximizeRequest || overridingNoMaximize)) || - requestsFakeFullscreen) { + if ((requestsFullscreen && (!(PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN) || overridingNoFullscreen)) || + (requestsMaximize && (!(PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE) || overridingNoMaximize)) || requestsFakeFullscreen) { // fix fullscreen on requested (basically do a switcheroo) if (PWORKSPACE->m_bHasFullscreenWindow) { const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); @@ -905,7 +915,7 @@ void Events::listener_fullscreenWindow(void* owner, void* data) { return; } - if (PWINDOW->isHidden() || PWINDOW->m_bNoFullscreenRequest) + if (PWINDOW->isHidden() || (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) return; bool requestedFullState = false; @@ -968,7 +978,7 @@ void Events::listener_activateXDG(wl_listener* listener, void* data) { const auto PWINDOW = g_pCompositor->getWindowFromSurface(E->surface); - if (!PWINDOW || PWINDOW == g_pCompositor->m_pLastWindow) + if (!PWINDOW || PWINDOW == g_pCompositor->m_pLastWindow || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE)) return; g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)PWINDOW)}); @@ -976,7 +986,7 @@ void Events::listener_activateXDG(wl_listener* listener, void* data) { PWINDOW->m_bIsUrgent = true; - if (!**PFOCUSONACTIVATE) + if (!**PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY)) return; if (PWINDOW->m_bIsFloating) @@ -1004,13 +1014,13 @@ void Events::listener_activateX11(void* owner, void* data) { return; } - if (PWINDOW == g_pCompositor->m_pLastWindow) + if (PWINDOW == g_pCompositor->m_pLastWindow || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE)) return; g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)PWINDOW)}); EMIT_HOOK_EVENT("urgent", PWINDOW); - if (!**PFOCUSONACTIVATE) + if (!**PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY)) return; if (PWINDOW->m_bIsFloating) @@ -1206,7 +1216,7 @@ void Events::listener_NewXDGDeco(wl_listener* listener, void* data) { void Events::listener_requestMaximize(void* owner, void* data) { const auto PWINDOW = (CWindow*)owner; - if (PWINDOW->m_bNoMaximizeRequest) + if (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE) return; Debug::log(LOG, "Maximize request for {}", PWINDOW); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index d5aba751..c5eb70a0 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -73,33 +73,34 @@ class CMonitor { CMonitorState state; // WLR stuff - wlr_damage_ring damage; - wlr_output* output = nullptr; - float refreshRate = 60; - int framesToSkip = 0; - int forceFullFrames = 0; - bool noFrameSchedule = false; - bool scheduledRecalc = false; - wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; - bool gammaChanged = false; - float xwaylandScale = 1.f; - std::array<float, 9> projMatrix = {0}; - - bool dpmsStatus = true; - bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. - bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed. - bool createdByUser = false; - uint32_t drmFormat = DRM_FORMAT_INVALID; - bool isUnsafeFallback = false; - - bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after - bool renderingActive = false; - - wl_event_source* renderTimer = nullptr; // for RAT - bool RATScheduled = false; - CTimer lastPresentationTimer; - - SMonitorRule activeMonitorRule; + wlr_damage_ring damage; + wlr_output* output = nullptr; + float refreshRate = 60; + int framesToSkip = 0; + int forceFullFrames = 0; + bool noFrameSchedule = false; + bool scheduledRecalc = false; + wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; + bool gammaChanged = false; + float xwaylandScale = 1.f; + std::array<float, 9> projMatrix = {0}; + std::optional<Vector2D> forceSize; + + bool dpmsStatus = true; + bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. + bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed. + bool createdByUser = false; + uint32_t drmFormat = DRM_FORMAT_INVALID; + bool isUnsafeFallback = false; + + bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after + bool renderingActive = false; + + wl_event_source* renderTimer = nullptr; // for RAT + bool RATScheduled = false; + CTimer lastPresentationTimer; + + SMonitorRule activeMonitorRule; // mirroring CMonitor* pMirrorOf = nullptr; diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 9e168df4..5bdf8748 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -225,10 +225,13 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); } else { - PWINDOW->m_vRealSize = calcSize; - PWINDOW->m_vRealPosition = calcPos; + CBox wb = {calcPos, calcSize}; + wb.round(); // avoid rounding mess - g_pXWaylandManager->setWindowSize(PWINDOW, calcSize); + PWINDOW->m_vRealSize = wb.size(); + PWINDOW->m_vRealPosition = wb.pos(); + + g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); } if (force) { @@ -644,8 +647,10 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn else PWINDOW->m_vPseudoSize.y -= pixResize.y * 2; - PWINDOW->m_vPseudoSize.x = std::clamp(PWINDOW->m_vPseudoSize.x, 30.0, PNODE->box.w); - PWINDOW->m_vPseudoSize.y = std::clamp(PWINDOW->m_vPseudoSize.y, 30.0, PNODE->box.h); + CBox wbox = PNODE->box; + wbox.round(); + + PWINDOW->m_vPseudoSize = {std::clamp(PWINDOW->m_vPseudoSize.x, 30.0, wbox.w), std::clamp(PWINDOW->m_vPseudoSize.y, 30.0, wbox.h)}; PWINDOW->m_vLastFloatingSize = PWINDOW->m_vPseudoSize; PNODE->recalcSizePosRecursive(**PANIMATE == 0); @@ -990,6 +995,8 @@ std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::str const auto ARGS = CVarList(message, 0, ' '); if (ARGS[0] == "togglesplit") { toggleSplit(header.pWindow); + } else if (ARGS[0] == "swapsplit") { + swapSplit(header.pWindow); } else if (ARGS[0] == "preselect") { std::string direction = ARGS[1]; @@ -1043,6 +1050,20 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) { PNODE->pParent->recalcSizePosRecursive(); } +void CHyprDwindleLayout::swapSplit(CWindow* pWindow) { + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE || !PNODE->pParent) + return; + + if (pWindow->m_bIsFullscreen) + return; + + std::swap(PNODE->pParent->children[0], PNODE->pParent->children[1]); + + PNODE->pParent->recalcSizePosRecursive(); +} + void CHyprDwindleLayout::replaceWindowDataWith(CWindow* from, CWindow* to) { const auto PNODE = getNodeFromWindow(from); diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index 780dd121..f5501b28 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -83,6 +83,7 @@ class CHyprDwindleLayout : public IHyprLayout { SDwindleNodeData* getMasterNodeOnWorkspace(const int&); void toggleSplit(CWindow*); + void swapSplit(CWindow*); eDirection overrideDirection = DIRECTION_DEFAULT; diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 34499ca5..49e20435 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -530,7 +530,7 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { // find whether there is a floating window below this one for (auto& w : g_pCompositor->m_vWindows) { if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && - !w->m_bNoFocus && w.get() != pWindow) { + !w->m_sAdditionalConfigData.noFocus && w.get() != pWindow) { if (VECINRECT((pWindow->m_vSize / 2.f + pWindow->m_vPosition), w->m_vPosition.x, w->m_vPosition.y, w->m_vPosition.x + w->m_vSize.x, w->m_vPosition.y + w->m_vSize.y)) { return w.get(); @@ -550,7 +550,7 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { // if not, floating window for (auto& w : g_pCompositor->m_vWindows) { if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && - !w->m_bNoFocus && w.get() != pWindow) + !w->m_sAdditionalConfigData.noFocus && w.get() != pWindow) return w.get(); } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 2d8bd1e8..3afe7949 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -39,6 +39,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["changegroupactive"] = changeGroupActive; m_mDispatchers["movegroupwindow"] = moveGroupWindow; m_mDispatchers["togglesplit"] = toggleSplit; + m_mDispatchers["swapsplit"] = swapSplit; m_mDispatchers["splitratio"] = alterSplitRatio; m_mDispatchers["focusmonitor"] = focusMonitor; m_mDispatchers["movecursortocorner"] = moveCursorToCorner; @@ -1293,6 +1294,21 @@ void CKeybindManager::toggleSplit(std::string args) { g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "togglesplit"); } +void CKeybindManager::swapSplit(std::string args) { + SLayoutMessageHeader header; + header.pWindow = g_pCompositor->m_pLastWindow; + + if (!header.pWindow) + return; + + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID); + + if (PWORKSPACE->m_bHasFullscreenWindow) + return; + + g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "swapsplit"); +} + void CKeybindManager::alterSplitRatio(std::string args) { std::optional<float> splitResult; bool exact = false; diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 7ca43ec1..7022593a 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -127,6 +127,7 @@ class CKeybindManager { static void alterSplitRatio(std::string); static void focusMonitor(std::string); static void toggleSplit(std::string); + static void swapSplit(std::string); static void moveCursorToCorner(std::string); static void moveCursor(std::string); static void workspaceOpt(std::string); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 079c0336..155be729 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -487,10 +487,15 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even return; if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) { - m_sCursorSurfaceInfo.wlSurface.unassign(); + + if (e->surface != m_sCursorSurfaceInfo.wlSurface.wlr()) { + m_sCursorSurfaceInfo.wlSurface.unassign(); + + if (e->surface) + m_sCursorSurfaceInfo.wlSurface.assign(e->surface); + } if (e->surface) { - m_sCursorSurfaceInfo.wlSurface.assign(e->surface); m_sCursorSurfaceInfo.vHotspot = {e->hotspot_x, e->hotspot_y}; m_sCursorSurfaceInfo.hidden = false; } else { @@ -645,9 +650,11 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { } // notify app if we didnt handle it - if (g_pCompositor->doesSeatAcceptInput(g_pCompositor->m_pLastFocus)) { + if (g_pCompositor->doesSeatAcceptInput(g_pCompositor->m_pLastFocus)) wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, e->time_msec, e->button, e->state); - } + + if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_pLastMonitor && PMON) + g_pCompositor->setActiveMonitor(PMON); } void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) { diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index dfd8d9f8..74189622 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1231,20 +1231,20 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { TRACY_GPU_COLLECT; - // calc frame damage - CRegion frameDamage{}; + if (!pMonitor->mirrors.empty()) { + CRegion frameDamage{}; - const auto TRANSFORM = wlr_output_transform_invert(pMonitor->output->transform); - wlr_region_transform(frameDamage.pixman(), pMonitor->lastFrameDamage.pixman(), TRANSFORM, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y); + const auto TRANSFORM = wlr_output_transform_invert(pMonitor->output->transform); + wlr_region_transform(frameDamage.pixman(), pMonitor->lastFrameDamage.pixman(), TRANSFORM, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y); - if (**PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || **PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR) - frameDamage.add(0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y); + if (**PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || **PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR) + frameDamage.add(0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y); - if (**PDAMAGEBLINK) - frameDamage.add(damage); + if (**PDAMAGEBLINK) + frameDamage.add(damage); - if (!pMonitor->mirrors.empty()) g_pHyprRenderer->damageMirrorsWith(pMonitor, frameDamage); + } pMonitor->renderingActive = false; @@ -1735,8 +1735,13 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR pMonitor->activeMonitorRule = *pMonitorRule; + if (pMonitor->forceSize.has_value()) + pMonitor->activeMonitorRule.resolution = pMonitor->forceSize.value(); + + const auto RULE = &pMonitor->activeMonitorRule; + // if it's disabled, disable and ignore - if (pMonitorRule->disabled) { + if (RULE->disabled) { if (pMonitor->m_bEnabled) pMonitor->onDisconnect(); @@ -1755,12 +1760,12 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR // Check if the rule isn't already applied // TODO: clean this up lol - if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && - DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->setScale == pMonitorRule->scale && - ((DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1)) || - pMonitorRule->offset == Vector2D(-INT32_MAX, -INT32_MAX)) && - pMonitor->transform == pMonitorRule->transform && pMonitorRule->enable10bit == pMonitor->enabled10bit && - !memcmp(&pMonitor->customDrmMode, &pMonitorRule->drmMode, sizeof(pMonitor->customDrmMode))) { + if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, RULE->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, RULE->resolution.y, 1) && + DELTALESSTHAN(pMonitor->refreshRate, RULE->refreshRate, 1) && pMonitor->setScale == RULE->scale && + ((DELTALESSTHAN(pMonitor->vecPosition.x, RULE->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, RULE->offset.y, 1)) || + RULE->offset == Vector2D(-INT32_MAX, -INT32_MAX)) && + pMonitor->transform == RULE->transform && RULE->enable10bit == pMonitor->enabled10bit && + !memcmp(&pMonitor->customDrmMode, &RULE->drmMode, sizeof(pMonitor->customDrmMode))) { Debug::log(LOG, "Not applying a new rule to {} because it's already applied!", pMonitor->szName); return true; @@ -1773,8 +1778,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR pMonitor->customDrmMode = {}; bool autoScale = false; - if (pMonitorRule->scale > 0.1) { - pMonitor->scale = pMonitorRule->scale; + if (RULE->scale > 0.1) { + pMonitor->scale = RULE->scale; } else { autoScale = true; const auto DEFAULTSCALE = pMonitor->getDefaultScale(); @@ -1784,21 +1789,21 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR wlr_output_state_set_scale(pMonitor->state.wlr(), pMonitor->scale); pMonitor->setScale = pMonitor->scale; - wlr_output_state_set_transform(pMonitor->state.wlr(), pMonitorRule->transform); - pMonitor->transform = pMonitorRule->transform; + wlr_output_state_set_transform(pMonitor->state.wlr(), RULE->transform); + pMonitor->transform = RULE->transform; - const auto WLRREFRESHRATE = (wlr_backend_is_wl(pMonitor->output->backend) || wlr_backend_is_x11(pMonitor->output->backend)) ? 0 : pMonitorRule->refreshRate * 1000; + const auto WLRREFRESHRATE = (wlr_backend_is_wl(pMonitor->output->backend) || wlr_backend_is_x11(pMonitor->output->backend)) ? 0 : RULE->refreshRate * 1000; // loop over modes and choose an appropriate one. - if (pMonitorRule->resolution != Vector2D() && pMonitorRule->resolution != Vector2D(-1, -1) && pMonitorRule->resolution != Vector2D(-1, -2)) { - if (!wl_list_empty(&pMonitor->output->modes) && pMonitorRule->drmMode.type != DRM_MODE_TYPE_USERDEF) { + if (RULE->resolution != Vector2D() && RULE->resolution != Vector2D(-1, -1) && RULE->resolution != Vector2D(-1, -2)) { + if (!wl_list_empty(&pMonitor->output->modes) && RULE->drmMode.type != DRM_MODE_TYPE_USERDEF) { wlr_output_mode* mode; bool found = false; wl_list_for_each(mode, &pMonitor->output->modes, link) { // if delta of refresh rate, w and h chosen and mode is < 1 we accept it - if (DELTALESSTHAN(mode->width, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(mode->height, pMonitorRule->resolution.y, 1) && - DELTALESSTHAN(mode->refresh / 1000.f, pMonitorRule->refreshRate, 1)) { + if (DELTALESSTHAN(mode->width, RULE->resolution.x, 1) && DELTALESSTHAN(mode->height, RULE->resolution.y, 1) && + DELTALESSTHAN(mode->refresh / 1000.f, RULE->refreshRate, 1)) { wlr_output_state_set_mode(pMonitor->state.wlr(), mode); if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) { @@ -1806,8 +1811,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR continue; } - Debug::log(LOG, "Monitor {}: requested {:X0}@{:2f}, found available mode: {}x{}@{}mHz, applying.", pMonitor->output->name, pMonitorRule->resolution, - (float)pMonitorRule->refreshRate, mode->width, mode->height, mode->refresh); + Debug::log(LOG, "Monitor {}: requested {:X0}@{:2f}, found available mode: {}x{}@{}mHz, applying.", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate, mode->width, mode->height, mode->refresh); found = true; @@ -1819,9 +1824,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR } if (!found) { - wlr_output_state_set_custom_mode(pMonitor->state.wlr(), (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, WLRREFRESHRATE); - pMonitor->vecSize = pMonitorRule->resolution; - pMonitor->refreshRate = pMonitorRule->refreshRate; + wlr_output_state_set_custom_mode(pMonitor->state.wlr(), (int)RULE->resolution.x, (int)RULE->resolution.y, WLRREFRESHRATE); + pMonitor->vecSize = RULE->resolution; + pMonitor->refreshRate = RULE->refreshRate; if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) { Debug::log(ERR, "Custom resolution FAILED, falling back to preferred"); @@ -1829,47 +1834,47 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output); if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->ID, pMonitorRule->resolution, - (float)pMonitorRule->refreshRate); + Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->ID, RULE->resolution, + (float)RULE->refreshRate); return true; } // Preferred is valid wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE); - Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, - pMonitorRule->resolution, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); + Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f; pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height); } else { - Debug::log(LOG, "Set a custom mode {:X0}@{:2f} (mode not found in monitor modes)", pMonitorRule->resolution, (float)pMonitorRule->refreshRate); + Debug::log(LOG, "Set a custom mode {:X0}@{:2f} (mode not found in monitor modes)", RULE->resolution, (float)RULE->refreshRate); } } } else { // custom resolution bool fail = false; - if (pMonitorRule->drmMode.type == DRM_MODE_TYPE_USERDEF) { + if (RULE->drmMode.type == DRM_MODE_TYPE_USERDEF) { if (!wlr_output_is_drm(pMonitor->output)) { Debug::log(ERR, "Tried to set custom modeline on non-DRM output"); fail = true; } else { - auto* mode = wlr_drm_connector_add_mode(pMonitor->output, &pMonitorRule->drmMode); + auto* mode = wlr_drm_connector_add_mode(pMonitor->output, &RULE->drmMode); if (mode) { wlr_output_state_set_mode(pMonitor->state.wlr(), mode); - pMonitor->customDrmMode = pMonitorRule->drmMode; + pMonitor->customDrmMode = RULE->drmMode; } else { Debug::log(ERR, "wlr_drm_connector_add_mode failed"); fail = true; } } } else { - wlr_output_state_set_custom_mode(pMonitor->state.wlr(), (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, WLRREFRESHRATE); + wlr_output_state_set_custom_mode(pMonitor->state.wlr(), (int)RULE->resolution.x, (int)RULE->resolution.y, WLRREFRESHRATE); } - pMonitor->vecSize = pMonitorRule->resolution; - pMonitor->refreshRate = pMonitorRule->refreshRate; + pMonitor->vecSize = RULE->resolution; + pMonitor->refreshRate = RULE->refreshRate; if (fail || !wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) { Debug::log(ERR, "Custom resolution FAILED, falling back to preferred"); @@ -1877,25 +1882,25 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output); if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->output->name, pMonitorRule->resolution, - (float)pMonitorRule->refreshRate); + Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate); return true; } // Preferred is valid wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE); - Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, - pMonitorRule->resolution, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); + Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f; pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height); pMonitor->customDrmMode = {}; } else { - Debug::log(LOG, "Set a custom mode {:X0}@{:2f} (mode not found in monitor modes)", pMonitorRule->resolution, (float)pMonitorRule->refreshRate); + Debug::log(LOG, "Set a custom mode {:X0}@{:2f} (mode not found in monitor modes)", RULE->resolution, (float)RULE->refreshRate); } } - } else if (pMonitorRule->resolution != Vector2D()) { + } else if (RULE->resolution != Vector2D()) { if (!wl_list_empty(&pMonitor->output->modes)) { wlr_output_mode* mode; float currentWidth = 0; @@ -1904,7 +1909,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR bool success = false; //(-1,-1) indicates a preference to refreshrate over resolution, (-1,-2) preference to resolution - if (pMonitorRule->resolution == Vector2D(-1, -1)) { + if (RULE->resolution == Vector2D(-1, -1)) { wl_list_for_each(mode, &pMonitor->output->modes, link) { if ((mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= (currentRefresh - 1000.f)) || mode->refresh > (currentRefresh + 3000.f)) { wlr_output_state_set_mode(pMonitor->state.wlr(), mode); @@ -1932,22 +1937,21 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR } if (!success) { - Debug::log(LOG, "Monitor {}: REJECTED mode: {:X0}@{:2f}! Falling back to preferred: {}x{}@{:2f}", pMonitor->output->name, pMonitorRule->resolution, - (float)pMonitorRule->refreshRate, mode->width, mode->height, mode->refresh / 1000.f); + Debug::log(LOG, "Monitor {}: REJECTED mode: {:X0}@{:2f}! Falling back to preferred: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate, mode->width, mode->height, mode->refresh / 1000.f); const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output); if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->ID, pMonitorRule->resolution, - (float)pMonitorRule->refreshRate); + Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->ID, RULE->resolution, (float)RULE->refreshRate); return true; } // Preferred is valid wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE); - Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, - pMonitorRule->resolution, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); + Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f; pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height); @@ -1976,8 +1980,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR continue; } - Debug::log(LOG, "Monitor {}: requested {:X0}@{:2f}, found available mode: {}x{}@{}mHz, applying.", pMonitor->output->name, pMonitorRule->resolution, - (float)pMonitorRule->refreshRate, mode->width, mode->height, mode->refresh); + Debug::log(LOG, "Monitor {}: requested {:X0}@{:2f}, found available mode: {}x{}@{}mHz, applying.", pMonitor->output->name, RULE->resolution, + (float)RULE->refreshRate, mode->width, mode->height, mode->refresh); pMonitor->refreshRate = mode->refresh / 1000.f; pMonitor->vecSize = Vector2D(mode->width, mode->height); @@ -2075,14 +2079,14 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR bool set10bit = false; pMonitor->drmFormat = DRM_FORMAT_INVALID; - for (auto& fmt : formats[(int)!pMonitorRule->enable10bit]) { + for (auto& fmt : formats[(int)!RULE->enable10bit]) { wlr_output_state_set_render_format(pMonitor->state.wlr(), fmt.second); if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) { Debug::log(ERR, "output {} failed basic test on format {}", pMonitor->szName, fmt.first); } else { Debug::log(LOG, "output {} succeeded basic test on format {}", pMonitor->szName, fmt.first); - if (pMonitorRule->enable10bit && fmt.first.contains("101010")) + if (RULE->enable10bit && fmt.first.contains("101010")) set10bit = true; pMonitor->drmFormat = fmt.second; @@ -2146,7 +2150,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR void CHyprRenderer::setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY, bool force) { m_bCursorHasSurface = surf; - if ((surf == m_sLastCursorData.surf || m_bCursorHidden) && !force) + if ((surf == m_sLastCursorData.surf || m_bCursorHidden) && hotspotX == m_sLastCursorData.hotspotX && hotspotY == m_sLastCursorData.hotspotY && !force) return; m_sLastCursorData.name = ""; @@ -2356,6 +2360,9 @@ bool CHyprRenderer::canSkipBackBufferClear(CMonitor* pMonitor) { void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) { pMonitor->solitaryClient = nullptr; // reset it, if we find one it will be set. + if (g_pHyprNotificationOverlay->hasAny()) + return; + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace); if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->specialWorkspaceID || |