Merge branch 'hyprwm:main' into main

This commit is contained in:
function i_use_lfs_btw() 2025-12-02 17:10:02 +03:00 committed by GitHub
commit 6c688e7f85
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 1535 additions and 952 deletions

View file

@ -33,11 +33,23 @@ find_package(PkgConfig REQUIRED)
# provide a .pc file and won't be detected this way
pkg_check_modules(udis_dep IMPORTED_TARGET udis86>=1.7.2)
# Fallback to subproject
# Find non-pkgconfig udis86, otherwise fallback to subproject
if(NOT udis_dep_FOUND)
add_subdirectory("subprojects/udis86")
include_directories("subprojects/udis86")
message(STATUS "udis86 dependency not found, falling back to subproject")
find_library(udis_nopc udis86)
if(NOT("${udis_nopc}" MATCHES "udis_nopc-NOTFOUND"))
message(STATUS "Found udis86 at ${udis_nopc}")
else()
add_subdirectory("subprojects/udis86")
include_directories("subprojects/udis86")
message(STATUS "udis86 dependency not found, falling back to subproject")
endif()
endif()
find_library(librt rt)
if("${librt}" MATCHES "librt-NOTFOUND")
unset(LIBRT)
else()
set(LIBRT rt)
endif()
if(CMAKE_BUILD_TYPE)
@ -358,7 +370,7 @@ message(STATUS "Setting link libraries")
target_link_libraries(
Hyprland
rt
${LIBRT}
PkgConfig::aquamarine_dep
PkgConfig::hyprlang_dep
PkgConfig::hyprutils_dep
@ -367,6 +379,8 @@ target_link_libraries(
PkgConfig::deps)
if(udis_dep_FOUND)
target_link_libraries(Hyprland PkgConfig::udis_dep)
elseif(NOT("${udis_nopc}" MATCHES "udis_nopc-NOTFOUND"))
target_link_libraries(Hyprland ${udis_nopc})
else()
target_link_libraries(Hyprland libudis86)
endif()

60
flake.lock generated
View file

@ -16,11 +16,11 @@
]
},
"locked": {
"lastModified": 1762356719,
"narHash": "sha256-qwd/xdoOya1m8FENle+4hWnydCtlXUWLAW/Auk6WL7s=",
"lastModified": 1763922789,
"narHash": "sha256-XnkWjCpeXfip9tqYdL0b0zzBDjq+dgdISvEdSVGdVyA=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "6d0b3567584691bf9d8fedb5d0093309e2f979c7",
"rev": "a20a0e67a33b6848378a91b871b89588d3a12573",
"type": "github"
},
"original": {
@ -32,11 +32,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1747046372,
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"type": "github"
},
"original": {
@ -105,11 +105,11 @@
]
},
"locked": {
"lastModified": 1762462052,
"narHash": "sha256-6roLYzcDf4V38RUMSqycsOwAnqfodL6BmhRkUtwIgdA=",
"lastModified": 1763733840,
"narHash": "sha256-JnET78yl5RvpGuDQy3rCycOCkiKoLr5DN1fPhRNNMco=",
"owner": "hyprwm",
"repo": "hyprgraphics",
"rev": "ffc999d980c7b3bca85d3ebd0a9fbadf984a8162",
"rev": "8f1bec691b2d198c60cccabca7a94add2df4ed1a",
"type": "github"
},
"original": {
@ -144,11 +144,11 @@
]
},
"locked": {
"lastModified": 1762755186,
"narHash": "sha256-ZjjETUHtoEhVN7JI1Cbt3p/KcXpK8ZQaPHx7UkG1OgA=",
"lastModified": 1763727565,
"narHash": "sha256-vRff/2R1U1jzPBy4OODqh2kfUzmizW/nfV2ROzTDIKo=",
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"rev": "66356e20a8ed348aa49c1b9ceace786e224225b3",
"rev": "7724d3a12a0453e7aae05f2ef39474219f05a4b4",
"type": "github"
},
"original": {
@ -193,11 +193,11 @@
]
},
"locked": {
"lastModified": 1763254292,
"narHash": "sha256-JNgz3Fz2KMzkT7aR72wsgu/xNeJB//LSmdilh8Z/Zao=",
"lastModified": 1763819661,
"narHash": "sha256-0jLarTR/BLWdGlboM86bPVP2zKJNI2jvo3JietnDkOM=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "deea98d5b61d066bdc7a68163edd2c4bd28d3a6b",
"rev": "a318deec0c12409ec39c68d2be8096b636dc2a5c",
"type": "github"
},
"original": {
@ -238,11 +238,11 @@
]
},
"locked": {
"lastModified": 1762463729,
"narHash": "sha256-2fYkU/mdz8WKY3dkDPlE/j6hTxIwqultsx4gMMsMns0=",
"lastModified": 1763503177,
"narHash": "sha256-VPoiswJBBmTLVuNncvT/8FpFR+sYcAi/LgP/zTZ+5rA=",
"owner": "hyprwm",
"repo": "hyprtoolkit",
"rev": "88483bdee5329ec985f0c8f834c519cd18cfe532",
"rev": "f4e1e12755567ecf39090203b8f43eace8279630",
"type": "github"
},
"original": {
@ -261,11 +261,11 @@
]
},
"locked": {
"lastModified": 1763323331,
"narHash": "sha256-+Z0OfCo1MS8/aIutSAW5aJR9zTae1wz9kcJYMgpwN6M=",
"lastModified": 1763996058,
"narHash": "sha256-DsqzFZvrEV+aDmavjaD4/bk5qxeZwhGxPWBQdpFyM9Y=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "0c6411851cc779d551edc89b83966696201611aa",
"rev": "0168583075baffa083032ed13a8bea8ea12f281a",
"type": "github"
},
"original": {
@ -284,11 +284,11 @@
]
},
"locked": {
"lastModified": 1755184602,
"narHash": "sha256-RCBQN8xuADB0LEgaKbfRqwm6CdyopE1xIEhNc67FAbw=",
"lastModified": 1763640274,
"narHash": "sha256-Uan1Nl9i4TF/kyFoHnTq1bd/rsWh4GAK/9/jDqLbY5A=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "b3b0f1f40ae09d4447c20608e5a4faf8bf3c492d",
"rev": "f6cf414ca0e16a4d30198fd670ec86df3c89f671",
"type": "github"
},
"original": {
@ -299,11 +299,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1763283776,
"narHash": "sha256-Y7TDFPK4GlqrKrivOcsHG8xSGqQx3A6c+i7novT85Uk=",
"lastModified": 1763966396,
"narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "50a96edd8d0db6cc8db57dab6bb6d6ee1f3dc49a",
"rev": "5ae3b07d8d6527c42f17c876e404993199144b6a",
"type": "github"
},
"original": {
@ -322,11 +322,11 @@
]
},
"locked": {
"lastModified": 1763319842,
"narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=",
"lastModified": 1763988335,
"narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761",
"rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce",
"type": "github"
},
"original": {

View file

@ -14,6 +14,7 @@
#include <src/desktop/rule/windowRule/WindowRuleEffectContainer.hpp>
#include <src/desktop/rule/windowRule/WindowRuleApplicator.hpp>
#include <src/Compositor.hpp>
#include <src/desktop/state/FocusState.hpp>
#undef private
#include <hyprutils/utils/ScopeGuard.hpp>
@ -45,7 +46,7 @@ static SDispatchResult test(std::string in) {
// Trigger a snap move event for the active window
static SDispatchResult snapMove(std::string in) {
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW->m_isFloating)
return {.success = false, .error = "Window must be floating"};
@ -259,13 +260,15 @@ static SDispatchResult addRule(std::string in) {
}
static SDispatchResult checkRule(std::string in) {
if (!g_pCompositor->m_lastWindow)
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window"};
if (!g_pCompositor->m_lastWindow->m_ruleApplicator->m_otherProps.props.contains(ruleIDX))
if (!PLASTWINDOW->m_ruleApplicator->m_otherProps.props.contains(ruleIDX))
return {.success = false, .error = "No rule"};
if (g_pCompositor->m_lastWindow->m_ruleApplicator->m_otherProps.props[ruleIDX]->effect != "effect")
if (PLASTWINDOW->m_ruleApplicator->m_otherProps.props[ruleIDX]->effect != "effect")
return {.success = false, .error = "Effect isn't \"effect\""};
return {};

View file

@ -53,7 +53,7 @@ static bool test() {
NLog::log("{}Testing new_window_takes_over_fullscreen", Colors::YELLOW);
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 0"));
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 0"));
Tests::spawnKitty("kitty_A");
@ -73,7 +73,16 @@ static bool test() {
EXPECT_CONTAINS(str, "kitty_A");
}
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 1"));
OK(getFromSocket("/dispatch focuswindow class:kitty_B"));
{
// should be ignored as per focus_under_fullscreen 0
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "kitty_A");
}
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 1"));
Tests::spawnKitty("kitty_C");
@ -83,7 +92,7 @@ static bool test() {
EXPECT_CONTAINS(str, "kitty_C");
}
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 2"));
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 2"));
Tests::spawnKitty("kitty_D");
@ -93,7 +102,7 @@ static bool test() {
EXPECT_CONTAINS(str, "kitty_D");
}
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 0"));
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 0"));
Tests::killAllWindows();
@ -138,6 +147,7 @@ static bool test() {
Tests::spawnKitty("kitty_A");
Tests::spawnKitty("kitty_B");
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
{

View file

@ -1,6 +1,9 @@
#include <cmath>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <thread>
#include <hyprutils/os/Process.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
@ -11,9 +14,9 @@
static int ret = 0;
static bool spawnKitty(const std::string& class_) {
static bool spawnKitty(const std::string& class_, const std::vector<std::string>& args = {}) {
NLog::log("{}Spawning {}", Colors::YELLOW, class_);
if (!Tests::spawnKitty(class_)) {
if (!Tests::spawnKitty(class_, args)) {
NLog::log("{}Error: {} did not spawn", Colors::RED, class_);
return false;
}
@ -193,6 +196,153 @@ static void testGroupRules() {
Tests::killAllWindows();
}
static bool isActiveWindow(const std::string& class_, char fullscreen, bool log = true) {
std::string activeWin = getFromSocket("/activewindow");
auto winClass = getWindowAttribute(activeWin, "class:");
auto winFullscreen = getWindowAttribute(activeWin, "fullscreen:").back();
if (winClass.substr(strlen("class: ")) == class_ && winFullscreen == fullscreen)
return true;
else {
if (log)
NLog::log("{}Wrong active window: expected class {} fullscreen '{}', found class {}, fullscreen '{}'", Colors::RED, class_, fullscreen, winClass, winFullscreen);
return false;
}
}
static bool waitForActiveWindow(const std::string& class_, char fullscreen, int maxTries = 50) {
int cnt = 0;
while (!isActiveWindow(class_, fullscreen, false)) {
++cnt;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (cnt > maxTries) {
return isActiveWindow(class_, fullscreen, true);
}
}
return true;
}
/// Tests behavior of a window being focused when on that window's workspace
/// another fullscreen window exists.
static bool testWindowFocusOnFullscreenConflict() {
if (!spawnKitty("kitty_A"))
return false;
if (!spawnKitty("kitty_B"))
return false;
OK(getFromSocket("/keyword misc:focus_on_activate true"));
auto spawnKittyActivating = [] -> std::string {
// `XXXXXX` is what `mkstemp` expects to find in the string
std::string tmpFilename = (std::filesystem::temp_directory_path() / "XXXXXX").string();
int fd = mkstemp(tmpFilename.data());
if (fd < 0) {
NLog::log("{}Error: could not create tmp file: errno {}", Colors::RED, errno);
return "";
}
(void)close(fd);
bool ok = spawnKitty("kitty_activating",
{"-o", "allow_remote_control=yes", "--", "/bin/sh", "-c", "while [ -f \"" + tmpFilename + "\" ]; do :; done; kitten @ focus-window; sleep infinity"});
if (!ok) {
NLog::log("{}Error: failed to spawn kitty", Colors::RED);
return "";
}
return tmpFilename;
};
// Unfullscreen on conflict
{
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 2"));
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus the same window
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus a different window
OK(getFromSocket("/dispatch focuswindow class:kitty_B"));
EXPECT(isActiveWindow("kitty_B", '0'), true);
// Make a window that will request focus
const std::string removeToActivate = spawnKittyActivating();
if (removeToActivate.empty())
return false;
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
std::filesystem::remove(removeToActivate);
EXPECT(waitForActiveWindow("kitty_activating", '0'), true);
OK(getFromSocket("/dispatch forcekillactive"));
Tests::waitUntilWindowsN(2);
}
// Take over on conflict
{
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 1"));
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus the same window
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus a different window
OK(getFromSocket("/dispatch focuswindow class:kitty_B"));
EXPECT(isActiveWindow("kitty_B", '2'), true);
OK(getFromSocket("/dispatch fullscreenstate 0 0"));
// Make a window that will request focus
const std::string removeToActivate = spawnKittyActivating();
if (removeToActivate.empty())
return false;
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
std::filesystem::remove(removeToActivate);
EXPECT(waitForActiveWindow("kitty_activating", '2'), true);
OK(getFromSocket("/dispatch forcekillactive"));
Tests::waitUntilWindowsN(2);
}
// Keep the old focus on conflict
{
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 0"));
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus the same window
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Make a window that will request focus - the setting is treated normally
const std::string removeToActivate = spawnKittyActivating();
if (removeToActivate.empty())
return false;
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
std::filesystem::remove(removeToActivate);
EXPECT(waitForActiveWindow("kitty_A", '2'), true);
}
NLog::log("{}Reloading config", Colors::YELLOW);
OK(getFromSocket("/reload"));
NLog::log("{}Killing all windows", Colors::YELLOW);
Tests::killAllWindows();
NLog::log("{}Expecting 0 windows", Colors::YELLOW);
EXPECT(Tests::windowCount(), 0);
return true;
}
static bool test() {
NLog::log("{}Testing windows", Colors::GREEN);
@ -256,16 +406,7 @@ static bool test() {
getFromSocket("/dispatch exec xeyes");
NLog::log("{}Keep checking if xeyes spawned", Colors::YELLOW);
int counter = 0;
while (Tests::windowCount() != 3) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (counter > 50) {
EXPECT(Tests::windowCount(), 3);
return !ret;
}
}
Tests::waitUntilWindowsN(3);
NLog::log("{}Expecting 3 windows", Colors::YELLOW);
EXPECT(Tests::windowCount(), 3);
@ -292,6 +433,36 @@ static bool test() {
getFromSocket("/dispatch workspace 1");
if (!testWindowFocusOnFullscreenConflict()) {
ret = 1;
return false;
}
NLog::log("{}Testing spawning a floating window over a fullscreen window", Colors::YELLOW);
{
if (!spawnKitty("kitty_A"))
return false;
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(Tests::windowCount(), 1);
OK(getFromSocket("/dispatch exec [float] kitty"));
Tests::waitUntilWindowsN(2);
OK(getFromSocket("/dispatch focuswindow class:^kitty$"));
const auto focused1 = getFromSocket("/activewindow");
EXPECT_CONTAINS(focused1, "class: kitty\n");
OK(getFromSocket("/dispatch killwindow activewindow"));
Tests::waitUntilWindowsN(1);
// The old window should be focused again
const auto focused2 = getFromSocket("/activewindow");
EXPECT_CONTAINS(focused2, "class: kitty_A\n");
NLog::log("{}Killing all windows", Colors::YELLOW);
Tests::killAllWindows();
}
NLog::log("{}Testing minsize/maxsize rules for tiled windows", Colors::YELLOW);
{
// Enable the config for testing, test max/minsize for tiled windows and centering
@ -397,6 +568,34 @@ static bool test() {
OK(getFromSocket("/reload"));
Tests::killAllWindows();
// test persistent_size between floating window launches
OK(getFromSocket("/keyword windowrule match:class persistent_size_kitty, persistent_size true, float true"));
if (!spawnKitty("persistent_size_kitty"))
return false;
OK(getFromSocket("/dispatch resizeactive exact 600 400"))
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "size: 600,400");
EXPECT_CONTAINS(str, "floating: 1");
}
Tests::killAllWindows();
if (!spawnKitty("persistent_size_kitty"))
return false;
{
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "size: 600,400");
EXPECT_CONTAINS(str, "floating: 1");
}
OK(getFromSocket("/reload"));
Tests::killAllWindows();
OK(getFromSocket("/keyword general:border_size 0"));
OK(getFromSocket("/keyword windowrule match:float true, border_size 10"));

View file

@ -4,6 +4,7 @@
#include "Compositor.hpp"
#include "debug/Log.hpp"
#include "desktop/DesktopTypes.hpp"
#include "desktop/state/FocusState.hpp"
#include "helpers/Splashes.hpp"
#include "config/ConfigValue.hpp"
#include "config/ConfigWatcher.hpp"
@ -560,9 +561,6 @@ void CCompositor::cleanup() {
// still in a normal working state.
g_pPluginSystem->unloadAllPlugins();
m_lastFocus.reset();
m_lastWindow.reset();
m_workspaces.clear();
m_windows.clear();
@ -951,7 +949,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (w->m_isX11 && w->isX11OverrideRedirect() && !w->m_xwaylandSurface->wantsFocus()) {
// Override Redirect
return g_pCompositor->m_lastWindow.lock(); // we kinda trick everything here.
return Desktop::focusState()->window(); // we kinda trick everything here.
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
}
@ -1115,201 +1113,6 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
return nullptr;
}
void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface, bool preserveFocusHistory) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
static auto PMODALPARENTBLOCKING = CConfigValue<Hyprlang::INT>("general:modal_parent_blocking");
if (*PMODALPARENTBLOCKING && pWindow && pWindow->m_xdgSurface && pWindow->m_xdgSurface->m_toplevel && pWindow->m_xdgSurface->m_toplevel->anyChildModal()) {
Debug::log(LOG, "Refusing focus to window shadowed by modal dialog");
return;
}
if (!pWindow || !pWindow->priorityFocus()) {
if (g_pSessionLockManager->isSessionLocked()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
return;
}
if (!g_pInputManager->m_exclusiveLSes.empty()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
return;
}
}
if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
return;
g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow);
if (!pWindow || !validMapped(pWindow)) {
if (m_lastWindow.expired() && !pWindow)
return;
const auto PLASTWINDOW = m_lastWindow.lock();
m_lastWindow.reset();
if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
PLASTWINDOW->updateDecorationValues();
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
}
g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr});
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
m_lastFocus.reset();
g_pInputManager->recheckIdleInhibitorStatus();
return;
}
if (pWindow->m_ruleApplicator->noFocus().valueOrDefault()) {
Debug::log(LOG, "Ignoring focus to nofocus window!");
return;
}
if (m_lastWindow.lock() == pWindow && g_pSeatManager->m_state.keyboardFocus == pSurface && g_pSeatManager->m_state.keyboardFocus)
return;
if (pWindow->m_pinned)
pWindow->m_workspace = m_lastMonitor->m_activeWorkspace;
const auto PMONITOR = pWindow->m_monitor.lock();
if (!pWindow->m_workspace || !pWindow->m_workspace->isVisible()) {
const auto PWORKSPACE = pWindow->m_workspace;
// This is to fix incorrect feedback on the focus history.
PWORKSPACE->m_lastFocusedWindow = pWindow;
if (m_lastMonitor->m_activeWorkspace)
PWORKSPACE->rememberPrevWorkspace(m_lastMonitor->m_activeWorkspace);
if (PWORKSPACE->m_isSpecialWorkspace)
m_lastMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor
else if (PMONITOR)
PMONITOR->changeWorkspace(PWORKSPACE, false, true);
// changeworkspace already calls focusWindow
return;
}
const auto PLASTWINDOW = m_lastWindow.lock();
m_lastWindow = pWindow;
/* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which
window focuses are "via keybinds" and which ones aren't. */
if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace != pWindow->m_workspace && !pWindow->m_pinned && !*PSPECIALFALLTHROUGH)
PMONITOR->setSpecialWorkspace(nullptr);
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
PLASTWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FOCUS);
PLASTWINDOW->updateDecorationValues();
if (!pWindow->m_isX11 || !pWindow->isX11OverrideRedirect())
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
}
m_lastWindow = PLASTWINDOW;
const auto PWINDOWSURFACE = pSurface ? pSurface : pWindow->m_wlSurface->resource();
focusSurface(PWINDOWSURFACE, pWindow);
g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
pWindow->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FOCUS);
pWindow->onFocusAnimUpdate();
pWindow->updateDecorationValues();
if (pWindow->m_isUrgent)
pWindow->m_isUrgent = false;
// Send an event
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = pWindow->m_class + "," + pWindow->m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(pWindow.get()))});
EMIT_HOOK_EVENT("activeWindow", pWindow);
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
g_pInputManager->recheckIdleInhibitorStatus();
if (!preserveFocusHistory) {
// move to front of the window history
const auto HISTORYPIVOT = std::ranges::find_if(m_windowFocusHistory, [&](const auto& other) { return other.lock() == pWindow; });
if (HISTORYPIVOT == m_windowFocusHistory.end())
Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow);
else
std::rotate(m_windowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
}
if (*PFOLLOWMOUSE == 0)
g_pInputManager->sendMotionEventsToFocused();
if (pWindow->m_groupData.pNextWindow)
pWindow->deactivateGroupMembers();
}
void CCompositor::focusSurface(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindowOwner) {
if (g_pSeatManager->m_state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->m_state.keyboardFocus == pWindowOwner->m_wlSurface->resource()))
return; // Don't focus when already focused on this.
if (g_pSessionLockManager->isSessionLocked() && pSurface && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
return;
if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(pSurface)) {
Debug::log(LOG, "surface {:x} won't receive kb focus because grab rejected it", rc<uintptr_t>(pSurface.get()));
return;
}
const auto PLASTSURF = m_lastFocus.lock();
// Unfocus last surface if should
if (m_lastFocus && !pWindowOwner)
g_pXWaylandManager->activateSurface(m_lastFocus.lock(), false);
if (!pSurface) {
g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""});
EMIT_HOOK_EVENT("keyboardFocus", SP<CWLSurfaceResource>{nullptr});
m_lastFocus.reset();
return;
}
if (g_pSeatManager->m_keyboard)
g_pSeatManager->setKeyboardFocus(pSurface);
if (pWindowOwner)
Debug::log(LOG, "Set keyboard focus to surface {:x}, with {}", rc<uintptr_t>(pSurface.get()), pWindowOwner);
else
Debug::log(LOG, "Set keyboard focus to surface {:x}", rc<uintptr_t>(pSurface.get()));
g_pXWaylandManager->activateSurface(pSurface, true);
m_lastFocus = pSurface;
EMIT_HOOK_EVENT("keyboardFocus", pSurface);
const auto SURF = CWLSurface::fromResource(pSurface);
const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
if (OLDSURF && OLDSURF->constraint())
OLDSURF->constraint()->deactivate();
if (SURF && SURF->constraint())
SURF->constraint()->activate();
}
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
for (auto const& lsl : monitor->m_layerSurfaceLayers | std::views::reverse) {
for (auto const& ls : lsl | std::views::reverse) {
@ -1390,7 +1193,7 @@ PHLWINDOW CCompositor::getUrgentWindow() {
}
bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
if (m_lastWindow.expired() && !m_lastFocus)
if (!Desktop::focusState()->window() && !Desktop::focusState()->surface())
return false;
if (!pWindow->m_isMapped)
@ -1398,7 +1201,7 @@ bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
const auto PSURFACE = pWindow->m_wlSurface->resource();
return PSURFACE == m_lastFocus || pWindow == m_lastWindow.lock();
return PSURFACE == Desktop::focusState()->surface() || pWindow == Desktop::focusState()->window();
}
void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
@ -1626,15 +1429,16 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
if (intersectLength > 0) {
// get idx
int windowIDX = -1;
for (size_t i = 0; i < g_pCompositor->m_windowFocusHistory.size(); ++i) {
if (g_pCompositor->m_windowFocusHistory[i].lock() == w) {
int windowIDX = -1;
const auto& HISTORY = Desktop::focusState()->windowHistory();
for (size_t i = 0; i < HISTORY.size(); ++i) {
if (HISTORY[i] == w) {
windowIDX = i;
break;
}
}
windowIDX = g_pCompositor->m_windowFocusHistory.size() - windowIDX;
windowIDX = Desktop::focusState()->windowHistory().size() - windowIDX;
if (windowIDX > leaderValue) {
leaderValue = windowIDX;
@ -1739,8 +1543,10 @@ static PHLWINDOW getWeakWindowPred(Iterator cur, Iterator end, Iterator begin, c
PHLWINDOW CCompositor::getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly, std::optional<bool> floating, bool visible, bool next) {
const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); };
// also m_vWindowFocusHistory has reverse order, so when it is next - we need to reverse again
return next ? getWeakWindowPred(std::ranges::find(m_windowFocusHistory | std::views::reverse, cur), m_windowFocusHistory.rend(), m_windowFocusHistory.rbegin(), FINDER) :
getWeakWindowPred(std::ranges::find(m_windowFocusHistory, cur), m_windowFocusHistory.end(), m_windowFocusHistory.begin(), FINDER);
return next ? getWeakWindowPred(std::ranges::find(Desktop::focusState()->windowHistory() | std::views::reverse, cur), Desktop::focusState()->windowHistory().rend(),
Desktop::focusState()->windowHistory().rbegin(), FINDER) :
getWeakWindowPred(std::ranges::find(Desktop::focusState()->windowHistory(), cur), Desktop::focusState()->windowHistory().end(),
Desktop::focusState()->windowHistory().begin(), FINDER);
}
PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional<bool> floating, bool visible, bool prev) {
@ -1834,7 +1640,7 @@ CBox CCompositor::calculateX11WorkArea() {
}
PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) {
return getMonitorInDirection(m_lastMonitor.lock(), dir);
return getMonitorInDirection(Desktop::focusState()->monitor(), dir);
}
PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const char& dir) {
@ -1997,12 +1803,12 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
PWORKSPACEA, PWORKSPACEA->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
if (pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id || pMonitorB->m_id == g_pCompositor->m_lastMonitor->m_id) {
const auto LASTWIN = pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow();
g_pCompositor->focusWindow(LASTWIN ? LASTWIN :
(g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING)));
if (pMonitorA->m_id == Desktop::focusState()->monitor()->m_id || pMonitorB->m_id == Desktop::focusState()->monitor()->m_id) {
const auto LASTWIN = pMonitorA->m_id == Desktop::focusState()->monitor()->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow();
Desktop::focusState()->fullWindowFocus(
LASTWIN ? LASTWIN : (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING)));
const auto PNEWWORKSPACE = pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id ? PWORKSPACEB : PWORKSPACEA;
const auto PNEWWORKSPACE = pMonitorA->m_id == Desktop::focusState()->monitor()->m_id ? PWORKSPACEB : PWORKSPACEA;
g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspace", .data = PNEWWORKSPACE->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspacev2", .data = std::format("{},{}", PNEWWORKSPACE->m_id, PNEWWORKSPACE->m_name)});
EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE);
@ -2020,7 +1826,7 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
if (name == "current")
return g_pCompositor->m_lastMonitor.lock();
return Desktop::focusState()->monitor();
else if (isDirection(name))
return getMonitorInDirection(name[0]);
else if (name[0] == '+' || name[0] == '-') {
@ -2041,7 +1847,7 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
int currentPlace = 0;
for (int i = 0; i < sc<int>(m_monitors.size()); i++) {
if (m_monitors[i] == m_lastMonitor) {
if (m_monitors[i] == Desktop::focusState()->monitor()) {
currentPlace = i;
break;
}
@ -2175,7 +1981,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
}
}
if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_lastMonitor) { // if it was active, preserve its' status. If it wasn't, don't.
if (SWITCHINGISACTIVE && POLDMON == Desktop::focusState()->monitor()) { // if it was active, preserve its' status. If it wasn't, don't.
Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active {} -> {}", pMonitor->activeWorkspaceID(), pWorkspace->m_id);
if (valid(pMonitor->m_activeWorkspace)) {
@ -2186,7 +1992,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
if (*PHIDESPECIALONWORKSPACECHANGE)
pMonitor->setSpecialWorkspace(nullptr);
setActiveMonitor(pMonitor);
Desktop::focusState()->rawMonitorFocus(pMonitor);
auto oldWorkspace = pMonitor->m_activeWorkspace;
pMonitor->m_activeWorkspace = pWorkspace;
@ -2247,6 +2053,7 @@ void CCompositor::changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, cons
sc<eFullscreenMode>(ON ? sc<uint8_t>(PWINDOW->m_fullscreenState.client) | sc<uint8_t>(MODE) : (sc<uint8_t>(PWINDOW->m_fullscreenState.client) & sc<uint8_t>(~MODE))));
}
// TODO: move fs functions to Desktop::
void CCompositor::setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE) {
if (PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault())
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = MODE});
@ -2387,16 +2194,16 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
auto regexp = trim(regexp_);
if (regexp.starts_with("active"))
return m_lastWindow.lock();
return Desktop::focusState()->window();
else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) {
// first floating on the current ws
if (!valid(m_lastWindow))
if (!Desktop::focusState()->window())
return nullptr;
const bool FLOAT = regexp.starts_with("floating");
for (auto const& w : m_windows) {
if (!w->m_isMapped || w->m_isFloating != FLOAT || w->m_workspace != m_lastWindow->m_workspace || w->isHidden())
if (!w->m_isMapped || w->m_isFloating != FLOAT || w->m_workspace != Desktop::focusState()->window()->m_workspace || w->isHidden())
continue;
return w;
@ -2502,16 +2309,14 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
if (*PNOWARPS && !force) {
const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_lastMonitor)
setActiveMonitor(PMONITORNEW);
Desktop::focusState()->rawMonitorFocus(PMONITORNEW);
return;
}
g_pPointerManager->warpTo(pos);
const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_lastMonitor)
setActiveMonitor(PMONITORNEW);
Desktop::focusState()->rawMonitorFocus(PMONITORNEW);
}
void CCompositor::closeWindow(PHLWINDOW pWindow) {
@ -2550,7 +2355,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
if (!args.contains(' ') && !args.contains('\t'))
return relativeTo;
const auto PMONITOR = m_lastMonitor;
const auto PMONITOR = Desktop::focusState()->monitor();
bool xIsPercent = false;
bool yIsPercent = false;
@ -2618,27 +2423,6 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO
return PWORKSPACE;
}
void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) {
if (m_lastMonitor == pMonitor)
return;
if (!pMonitor) {
m_lastMonitor.reset();
return;
}
const auto PWORKSPACE = pMonitor->m_activeWorkspace;
const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_id) : std::to_string(WORKSPACE_INVALID);
const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_name : "?";
g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmon", .data = pMonitor->m_name + "," + WORKSPACE_NAME});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmonv2", .data = pMonitor->m_name + "," + WORKSPACE_ID});
EMIT_HOOK_EVENT("focusedMon", pMonitor);
m_lastMonitor = pMonitor->m_self;
}
bool CCompositor::isWorkspaceSpecial(const WORKSPACEID& id) {
return id >= SPECIAL_WORKSPACE_START && id <= -2;
}
@ -2952,7 +2736,7 @@ void CCompositor::enterUnsafeState() {
m_unsafeState = true;
setActiveMonitor(m_unsafeOutput.lock());
Desktop::focusState()->rawMonitorFocus(m_unsafeOutput.lock());
}
void CCompositor::leaveUnsafeState() {
@ -3116,7 +2900,7 @@ bool CCompositor::shouldChangePreferredImageDescription() {
}
void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules, PHLWORKSPACE pWorkspace) {
if (!m_lastMonitor)
if (!Desktop::focusState()->monitor())
return;
std::vector<PHLWORKSPACE> persistentFound;
@ -3154,7 +2938,7 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
}
PWORKSPACE = getWorkspaceByID(id);
if (!PMONITOR)
PMONITOR = m_lastMonitor.lock();
PMONITOR = Desktop::focusState()->monitor();
if (!PWORKSPACE)
PWORKSPACE = createNewWorkspace(id, PMONITOR->m_id, wsname, false);

View file

@ -66,12 +66,6 @@ class CCompositor {
void bumpNofile();
void restoreNofile();
WP<CWLSurfaceResource> m_lastFocus;
PHLWINDOWREF m_lastWindow;
PHLMONITORREF m_lastMonitor;
std::vector<PHLWINDOWREF> m_windowFocusHistory; // first element is the most recently focused
bool m_readyToProcess = false;
bool m_sessionActive = true;
bool m_dpmsStateOn = true;
@ -99,8 +93,6 @@ class CCompositor {
PHLMONITOR getMonitorFromCursor();
PHLMONITOR getMonitorFromVector(const Vector2D&);
void removeWindowFromVectorSafe(PHLWINDOW);
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr, bool preserveFocusHistory = false);
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
bool monitorExists(PHLMONITOR);
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*, bool aboveLockscreen = false);
@ -150,7 +142,6 @@ class CCompositor {
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
[[nodiscard]] PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
void setActiveMonitor(PHLMONITOR);
bool isWorkspaceSpecial(const WORKSPACEID&);
WORKSPACEID getNewSpecialID();
void performUserChecks();

View file

@ -97,27 +97,29 @@ class CCssGapData : public ICustomConfigValueData {
int64_t m_bottom;
int64_t m_left;
void parseGapData(CVarList varlist) {
void parseGapData(CVarList2 varlist) {
const auto toInt = [](std::string_view string) -> int { return std::stoi(std::string(string)); };
switch (varlist.size()) {
case 1: {
*this = CCssGapData(std::stoi(varlist[0]));
*this = CCssGapData(toInt(varlist[0]));
break;
}
case 2: {
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]));
*this = CCssGapData(toInt(varlist[0]), toInt(varlist[1]));
break;
}
case 3: {
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]), std::stoi(varlist[2]));
*this = CCssGapData(toInt(varlist[0]), toInt(varlist[1]), toInt(varlist[2]));
break;
}
case 4: {
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]), std::stoi(varlist[2]), std::stoi(varlist[3]));
*this = CCssGapData(toInt(varlist[0]), toInt(varlist[1]), toInt(varlist[2]), toInt(varlist[3]));
break;
}
default: {
Debug::log(WARN, "Too many arguments provided for gaps.");
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]), std::stoi(varlist[2]), std::stoi(varlist[3]));
*this = CCssGapData(toInt(varlist[0]), toInt(varlist[1]), toInt(varlist[2]), toInt(varlist[3]));
break;
}
}

View file

@ -1279,11 +1279,11 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.data = SConfigOptionDescription::SBoolData{true},
},
SConfigOptionDescription{
.value = "misc:new_window_takes_over_fullscreen",
.description = "if there is a fullscreen or maximized window, decide whether a new tiled window opened should replace it, stay behind or disable the fullscreen/maximized "
"state. 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize [0/1/2]",
.value = "misc:on_focus_under_fullscreen",
.description = "if there is a fullscreen or maximized window, decide whether a tiled window requested to focus should replace it, stay behind or disable the "
"fullscreen/maximized state. 0 - ignore focus request (keep focus on fullscreen window), 1 - takes over, 2 - unfullscreen/unmaximize [0/1/2]",
.type = CONFIG_OPTION_INT,
.data = SConfigOptionDescription::SRangeData{0, 0, 2},
.data = SConfigOptionDescription::SRangeData{2, 0, 2},
},
SConfigOptionDescription{
.value = "misc:exit_window_retains_fullscreen",
@ -1946,12 +1946,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.type = CONFIG_OPTION_STRING_SHORT,
.data = SConfigOptionDescription::SStringData{"left"},
},
SConfigOptionDescription{
.value = "master:inherit_fullscreen",
.description = "inherit fullscreen status when cycling/swapping to another window (e.g. monocle layout)",
.type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{true},
},
SConfigOptionDescription{
.value = "master:slave_count_for_center_master",
.description = "when using orientation=center, make the master window centered only when at least this many slave windows are open. (Set 0 to always_center_master)",

View file

@ -17,6 +17,7 @@
#include "../desktop/rule/windowRule/WindowRule.hpp"
#include "../desktop/rule/layerRule/LayerRule.hpp"
#include "../debug/HyprCtl.hpp"
#include "../desktop/state/FocusState.hpp"
#include "defaultConfig.hpp"
#include "../render/Renderer.hpp"
@ -78,7 +79,7 @@ static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void**
const auto DATA = sc<CGradientValueData*>(*data);
CVarList varlist(V, 0, ' ');
CVarList2 varlist(std::string(V), 0, ' ');
DATA->m_colors.clear();
std::string parseError = "";
@ -87,7 +88,7 @@ static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void**
if (var.find("deg") != std::string::npos) {
// last arg
try {
DATA->m_angle = std::stoi(var.substr(0, var.find("deg"))) * (PI / 180.0); // radians
DATA->m_angle = std::stoi(std::string(var.substr(0, var.find("deg")))) * (PI / 180.0); // radians
} catch (...) {
Debug::log(WARN, "Error parsing gradient {}", V);
parseError = "Error parsing gradient " + V;
@ -103,7 +104,7 @@ static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void**
}
try {
const auto COL = configStringToInt(var);
const auto COL = configStringToInt(std::string(var));
if (!COL)
throw std::runtime_error(std::format("failed to parse {} as a color", var));
DATA->m_colors.emplace_back(COL.value());
@ -142,7 +143,7 @@ static Hyprlang::CParseResult configHandleGapSet(const char* VALUE, void** data)
*data = new CCssGapData();
const auto DATA = sc<CCssGapData*>(*data);
CVarList varlist(V);
CVarList2 varlist((std::string(V)));
Hyprlang::CParseResult result;
try {
@ -490,7 +491,7 @@ CConfigManager::CConfigManager() {
registerConfigVar("misc:session_lock_xray", Hyprlang::INT{0});
registerConfigVar("misc:close_special_on_empty", Hyprlang::INT{1});
registerConfigVar("misc:background_color", Hyprlang::INT{0xff111111});
registerConfigVar("misc:new_window_takes_over_fullscreen", Hyprlang::INT{0});
registerConfigVar("misc:on_focus_under_fullscreen", Hyprlang::INT{2});
registerConfigVar("misc:exit_window_retains_fullscreen", Hyprlang::INT{0});
registerConfigVar("misc:initial_workspace_tracking", Hyprlang::INT{1});
registerConfigVar("misc:middle_click_paste", Hyprlang::INT{1});
@ -619,7 +620,6 @@ CConfigManager::CConfigManager() {
registerConfigVar("master:new_on_active", {"none"});
registerConfigVar("master:new_on_top", Hyprlang::INT{0});
registerConfigVar("master:orientation", {"left"});
registerConfigVar("master:inherit_fullscreen", Hyprlang::INT{1});
registerConfigVar("master:allow_small_split", Hyprlang::INT{0});
registerConfigVar("master:smart_resizing", Hyprlang::INT{1});
registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1});
@ -2197,17 +2197,16 @@ bool CMonitorRuleParser::setReserved(const SMonitorAdditionalReservedArea& value
}
std::optional<std::string> CConfigManager::handleMonitor(const std::string& command, const std::string& args) {
// get the monitor config
const auto ARGS = CVarList(args);
const auto ARGS = CVarList2(std::string(args));
auto parser = CMonitorRuleParser(ARGS[0]);
auto parser = CMonitorRuleParser(std::string(ARGS[0]));
if (ARGS[1] == "disable" || ARGS[1] == "disabled" || ARGS[1] == "addreserved" || ARGS[1] == "transform") {
if (ARGS[1] == "disable" || ARGS[1] == "disabled")
parser.setDisabled();
else if (ARGS[1] == "transform") {
if (!parser.parseTransform(ARGS[2]))
if (!parser.parseTransform(std::string(ARGS[2])))
return parser.getError();
const auto TRANSFORM = parser.rule().transform;
@ -2223,7 +2222,10 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
return {};
} else if (ARGS[1] == "addreserved") {
try {
parser.setReserved({.top = std::stoi(ARGS[2]), .bottom = std::stoi(ARGS[3]), .left = std::stoi(ARGS[4]), .right = std::stoi(ARGS[5])});
parser.setReserved({.top = std::stoi(std::string(ARGS[2])),
.bottom = std::stoi(std::string(ARGS[3])),
.left = std::stoi(std::string(ARGS[4])),
.right = std::stoi(std::string(ARGS[5]))});
} catch (...) { return "parse error: invalid reserved area"; }
return {};
} else {
@ -2238,36 +2240,36 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
return {};
}
parser.parseMode(ARGS[1]);
parser.parsePosition(ARGS[2]);
parser.parseScale(ARGS[3]);
parser.parseMode(std::string(ARGS[1]));
parser.parsePosition(std::string(ARGS[2]));
parser.parseScale(std::string(ARGS[3]));
int argno = 4;
while (!ARGS[argno].empty()) {
if (ARGS[argno] == "mirror") {
parser.setMirror(ARGS[argno + 1]);
parser.setMirror(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "bitdepth") {
parser.parseBitdepth(ARGS[argno + 1]);
parser.parseBitdepth(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "cm") {
parser.parseCM(ARGS[argno + 1]);
parser.parseCM(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "sdrsaturation") {
parser.parseSDRSaturation(ARGS[argno + 1]);
parser.parseSDRSaturation(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "sdrbrightness") {
parser.parseSDRBrightness(ARGS[argno + 1]);
parser.parseSDRBrightness(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "transform") {
parser.parseTransform(ARGS[argno + 1]);
parser.parseTransform(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "vrr") {
parser.parseVRR(ARGS[argno + 1]);
parser.parseVRR(std::string(ARGS[argno + 1]));
argno++;
} else if (ARGS[argno] == "workspace") {
const auto& [id, name, isAutoID] = getWorkspaceIDNameFromString(ARGS[argno + 1]);
const auto& [id, name, isAutoID] = getWorkspaceIDNameFromString(std::string(ARGS[argno + 1]));
SWorkspaceRule wsRule;
wsRule.monitor = parser.name();
@ -2279,7 +2281,7 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
argno++;
} else {
Debug::log(ERR, "Config error: invalid monitor syntax at \"{}\"", ARGS[argno]);
return "invalid syntax at \"" + ARGS[argno] + "\"";
return "invalid syntax at \"" + std::string(ARGS[argno]) + "\"";
}
argno++;
@ -2580,14 +2582,14 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
auto assignRule = [&](std::string rule) -> std::optional<std::string> {
size_t delim = std::string::npos;
if ((delim = rule.find("gapsin:")) != std::string::npos) {
CVarList varlist = CVarList(rule.substr(delim + 7), 0, ' ');
wsRule.gapsIn = CCssGapData();
CVarList2 varlist(rule.substr(delim + 7), 0, ' ');
wsRule.gapsIn = CCssGapData();
try {
wsRule.gapsIn->parseGapData(varlist);
} catch (...) { return "Error parsing workspace rule gaps: {}", rule.substr(delim + 7); }
} else if ((delim = rule.find("gapsout:")) != std::string::npos) {
CVarList varlist = CVarList(rule.substr(delim + 8), 0, ' ');
wsRule.gapsOut = CCssGapData();
CVarList2 varlist(rule.substr(delim + 8), 0, ' ');
wsRule.gapsOut = CCssGapData();
try {
wsRule.gapsOut->parseGapData(varlist);
} catch (...) { return "Error parsing workspace rule gaps: {}", rule.substr(delim + 8); }
@ -2639,9 +2641,9 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
#undef CHECK_OR_THROW
CVarList rulesList{rules, 0, ',', true};
CVarList2 rulesList(std::string(rules), 0, ',', true);
for (auto const& r : rulesList) {
const auto R = assignRule(r);
const auto R = assignRule(std::string(r));
if (R.has_value())
return R;
}
@ -2660,9 +2662,9 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
}
std::optional<std::string> CConfigManager::handleSubmap(const std::string&, const std::string& submap) {
const auto SUBMAP = CConstVarList(submap);
m_currentSubmap.name = (SUBMAP[0] == "reset") ? "" : SUBMAP[0];
m_currentSubmap.reset = SUBMAP[1];
CVarList2 data((std::string(submap)));
m_currentSubmap.name = (data[0] == "reset") ? "" : data[0];
m_currentSubmap.reset = data[1];
return {};
}
@ -2761,7 +2763,7 @@ std::optional<std::string> CConfigManager::handlePlugin(const std::string& comma
}
std::optional<std::string> CConfigManager::handlePermission(const std::string& command, const std::string& value) {
CVarList data(value);
CVarList2 data((std::string(value)));
eDynamicPermissionType type = PERMISSION_TYPE_UNKNOWN;
eDynamicPermissionAllowMode mode = PERMISSION_RULE_ALLOW_MODE_UNKNOWN;
@ -2786,13 +2788,13 @@ std::optional<std::string> CConfigManager::handlePermission(const std::string& c
return "unknown permission allow mode";
if (m_isFirstLaunch)
g_pDynamicPermissionManager->addConfigPermissionRule(data[0], type, mode);
g_pDynamicPermissionManager->addConfigPermissionRule(std::string(data[0]), type, mode);
return {};
}
std::optional<std::string> CConfigManager::handleGesture(const std::string& command, const std::string& value) {
CConstVarList data(value);
CVarList2 data((std::string(value)));
size_t fingerCount = 0;
eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE;
@ -2861,7 +2863,7 @@ std::optional<std::string> CConfigManager::handleGesture(const std::string& comm
}
std::optional<std::string> CConfigManager::handleWindowrule(const std::string& command, const std::string& value) {
CVarList2 data(std::string{value}, 0, ',');
CVarList2 data((std::string(value)));
SP<Desktop::Rule::CWindowRule> rule = makeShared<Desktop::Rule::CWindowRule>();
@ -2900,7 +2902,7 @@ std::optional<std::string> CConfigManager::handleWindowrule(const std::string& c
}
std::optional<std::string> CConfigManager::handleLayerrule(const std::string& command, const std::string& value) {
CVarList2 data(std::string{value}, 0, ',');
CVarList2 data((std::string(value)));
SP<Desktop::Rule::CLayerRule> rule = makeShared<Desktop::Rule::CLayerRule>();

View file

@ -76,15 +76,15 @@ void NCrashReporter::createAndSaveCrash(int sig) {
reportPath += ".txt";
{
CBufFileWriter<64> stderr(2);
stderr += "Hyprland has crashed :( Consult the crash report at ";
CBufFileWriter<64> stderr_out(STDERR_FILENO);
stderr_out += "Hyprland has crashed :( Consult the crash report at ";
if (!reportPath.boundsExceeded()) {
stderr += reportPath.getStr();
stderr_out += reportPath.getStr();
} else {
stderr += "[ERROR: Crash report path does not fit into memory! Check if your $CACHE_HOME/$HOME is too deeply nested. Max 255 characters.]";
stderr_out += "[ERROR: Crash report path does not fit into memory! Check if your $CACHE_HOME/$HOME is too deeply nested. Max 255 characters.]";
}
stderr += " for more information.\n";
stderr.flush();
stderr_out += " for more information.\n";
stderr_out.flush();
}
reportFd = open(reportPath.getStr(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);

View file

@ -45,6 +45,7 @@ using namespace Hyprutils::OS;
#include "helpers/MiscFunctions.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/rule/Engine.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../version.h"
#include "../Compositor.hpp"
@ -255,12 +256,12 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
sc<int>(m->m_output->physicalSize.y), m->m_refreshRate, sc<int>(m->m_position.x), sc<int>(m->m_position.y), m->activeWorkspaceID(),
(!m->m_activeWorkspace ? "" : escapeJSONStrings(m->m_activeWorkspace->m_name)), m->activeSpecialWorkspaceID(),
escapeJSONStrings(m->m_activeSpecialWorkspace ? m->m_activeSpecialWorkspace->m_name : ""), sc<int>(m->m_reservedTopLeft.x), sc<int>(m->m_reservedTopLeft.y),
sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale, sc<int>(m->m_transform), (m == g_pCompositor->m_lastMonitor ? "true" : "false"),
(m->m_dpmsStatus ? "true" : "false"), (m->m_output->state->state().adaptiveSync ? "true" : "false"), rc<uint64_t>(m->m_solitaryClient.get()),
getSolitaryBlockedReason(m, format), (m->m_tearingState.activelyTearing ? "true" : "false"), getTearingBlockedReason(m, format), rc<uint64_t>(m->m_lastScanout.get()),
getDSBlockedReason(m, format), (m->m_enabled ? "false" : "true"), formatToString(m->m_output->state->state().drmFormat),
m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format), (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness),
(m->m_sdrSaturation), (m->m_sdrMinLuminance), (m->m_sdrMaxLuminance));
sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale, sc<int>(m->m_transform),
(m == Desktop::focusState()->monitor() ? "true" : "false"), (m->m_dpmsStatus ? "true" : "false"), (m->m_output->state->state().adaptiveSync ? "true" : "false"),
rc<uint64_t>(m->m_solitaryClient.get()), getSolitaryBlockedReason(m, format), (m->m_tearingState.activelyTearing ? "true" : "false"),
getTearingBlockedReason(m, format), rc<uint64_t>(m->m_lastScanout.get()), getDSBlockedReason(m, format), (m->m_enabled ? "false" : "true"),
formatToString(m->m_output->state->state().drmFormat), m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format),
(NCMType::toString(m->m_cmType)), (m->m_sdrBrightness), (m->m_sdrSaturation), (m->m_sdrMinLuminance), (m->m_sdrMaxLuminance));
} else {
result += std::format(
@ -274,7 +275,7 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
m->m_output->make, m->m_output->model, sc<int>(m->m_output->physicalSize.x), sc<int>(m->m_output->physicalSize.y), m->m_output->serial, m->activeWorkspaceID(),
(!m->m_activeWorkspace ? "" : m->m_activeWorkspace->m_name), m->activeSpecialWorkspaceID(), (m->m_activeSpecialWorkspace ? m->m_activeSpecialWorkspace->m_name : ""),
sc<int>(m->m_reservedTopLeft.x), sc<int>(m->m_reservedTopLeft.y), sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale,
sc<int>(m->m_transform), (m == g_pCompositor->m_lastMonitor ? "yes" : "no"), sc<int>(m->m_dpmsStatus), m->m_output->state->state().adaptiveSync,
sc<int>(m->m_transform), (m == Desktop::focusState()->monitor() ? "yes" : "no"), sc<int>(m->m_dpmsStatus), m->m_output->state->state().adaptiveSync,
rc<uint64_t>(m->m_solitaryClient.get()), getSolitaryBlockedReason(m, format), m->m_tearingState.activelyTearing, getTearingBlockedReason(m, format),
rc<uint64_t>(m->m_lastScanout.get()), getDSBlockedReason(m, format), !m->m_enabled, formatToString(m->m_output->state->state().drmFormat),
m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format), (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness),
@ -353,8 +354,8 @@ static std::string getGroupedData(PHLWINDOW w, eHyprCtlOutputFormat format) {
std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
auto getFocusHistoryID = [](PHLWINDOW wnd) -> int {
for (size_t i = 0; i < g_pCompositor->m_windowFocusHistory.size(); ++i) {
if (g_pCompositor->m_windowFocusHistory[i].lock() == wnd)
for (size_t i = 0; i < Desktop::focusState()->windowHistory().size(); ++i) {
if (Desktop::focusState()->windowHistory()[i].lock() == wnd)
return i;
}
return -1;
@ -524,11 +525,11 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
}
static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) {
if (!g_pCompositor->m_lastMonitor)
if (!Desktop::focusState()->monitor())
return "unsafe state";
std::string result = "";
auto w = g_pCompositor->m_lastMonitor->m_activeWorkspace;
auto w = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!valid(w))
return "internal error";
@ -578,7 +579,7 @@ static std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::strin
}
static std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return format == eHyprCtlOutputFormat::FORMAT_JSON ? "{}" : "Invalid";

View file

@ -5,6 +5,7 @@
#include "../render/pass/TexPassElement.hpp"
#include "../render/Renderer.hpp"
#include "../managers/animation/AnimationManager.hpp"
#include "../desktop/state/FocusState.hpp"
CHyprDebugOverlay::CHyprDebugOverlay() {
m_texture = makeShared<CTexture>();
@ -57,7 +58,7 @@ void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
m_monitor = pMonitor;
// anim data too
const auto PMONITORFORTICKS = g_pHyprRenderer->m_mostHzMonitor ? g_pHyprRenderer->m_mostHzMonitor.lock() : g_pCompositor->m_lastMonitor.lock();
const auto PMONITORFORTICKS = g_pHyprRenderer->m_mostHzMonitor ? g_pHyprRenderer->m_mostHzMonitor.lock() : Desktop::focusState()->monitor();
if (PMONITORFORTICKS == pMonitor) {
if (m_lastAnimationTicks.size() > sc<long unsigned int>(PMONITORFORTICKS->m_refreshRate))
m_lastAnimationTicks.pop_front();

View file

@ -1,4 +1,5 @@
#include "LayerSurface.hpp"
#include "state/FocusState.hpp"
#include "../Compositor.hpp"
#include "../events/Events.hpp"
#include "../protocols/LayerShell.hpp"
@ -16,7 +17,7 @@
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
auto pMonitor = resource->m_monitor.empty() ? g_pCompositor->m_lastMonitor.lock() : g_pCompositor->getMonitorFromName(resource->m_monitor);
auto pMonitor = resource->m_monitor.empty() ? Desktop::focusState()->monitor() : g_pCompositor->getMonitorFromName(resource->m_monitor);
pLS->m_surface->assign(resource->m_surface.lock(), pLS);
@ -173,7 +174,7 @@ void CLayerSurface::onMap() {
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
g_pCompositor->focusSurface(m_surface->resource());
Desktop::focusState()->rawSurfaceFocus(m_surface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);
@ -244,11 +245,12 @@ void CLayerSurface::onUnmap() {
// refocus if needed
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window
if (WASLASTFOCUS || (g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus->m_hlSurface && !g_pCompositor->m_lastFocus->m_hlSurface->keyboardFocusable())) {
if (WASLASTFOCUS ||
(Desktop::focusState()->surface() && Desktop::focusState()->surface()->m_hlSurface && !Desktop::focusState()->surface()->m_hlSurface->keyboardFocusable())) {
if (!g_pInputManager->refocusLastWindow(PMONITOR))
g_pInputManager->refocus();
} else if (g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus != m_surface->resource())
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_lastFocus.lock());
} else if (Desktop::focusState()->surface() && Desktop::focusState()->surface() != m_surface->resource())
g_pSeatManager->setKeyboardFocus(Desktop::focusState()->surface());
CBox geomFixed = {m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y, m_geometry.width, m_geometry.height};
g_pHyprRenderer->damageBox(geomFixed);
@ -374,7 +376,7 @@ void CLayerSurface::onCommit() {
if (WASLASTFOCUS && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
// so unfocus the surface here.
g_pCompositor->focusSurface(nullptr);
Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pInputManager->refocusLastWindow(m_monitor.lock());
} else if (WASLASTFOCUS && WASEXCLUSIVE && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
g_pInputManager->simulateMouseMovement();
@ -382,7 +384,7 @@ void CLayerSurface::onCommit() {
// if now exclusive and not previously
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
g_pCompositor->focusSurface(m_surface->resource());
Desktop::focusState()->rawSurfaceFocus(m_surface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);

View file

@ -1,6 +1,7 @@
#include "Subsurface.hpp"
#include "../events/Events.hpp"
#include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../desktop/Window.hpp"
#include "../config/ConfigValue.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/core/Subcompositor.hpp"
@ -163,7 +164,7 @@ void CSubsurface::onMap() {
void CSubsurface::onUnmap() {
damageLastArea();
if (m_wlSurface->resource() == g_pCompositor->m_lastFocus)
if (m_wlSurface->resource() == Desktop::focusState()->surface())
g_pInputManager->releaseAllMouseButtons();
g_pInputManager->simulateMouseMovement();

View file

@ -3,10 +3,16 @@
#include <hyprutils/animation/AnimatedVariable.hpp>
#include <re2/re2.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
#include <any>
#include <bit>
#include <string_view>
#include "Window.hpp"
#include "state/FocusState.hpp"
#include "../Compositor.hpp"
#include "../render/decorations/CHyprDropShadowDecoration.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
@ -121,9 +127,9 @@ CWindow::CWindow(SP<CXWaylandSurface> surface) : m_xwaylandSurface(surface) {
}
CWindow::~CWindow() {
if (g_pCompositor->m_lastWindow == m_self) {
g_pCompositor->m_lastFocus.reset();
g_pCompositor->m_lastWindow.reset();
if (Desktop::focusState()->window() == m_self) {
Desktop::focusState()->surface().reset();
Desktop::focusState()->window().reset();
}
m_events.destroy.emit();
@ -528,8 +534,6 @@ void CWindow::onUnmap() {
if (m_workspace->m_isSpecialWorkspace && m_workspace->getWindows() == 0)
m_lastWorkspace = m_monitor->activeWorkspaceID();
std::erase_if(g_pCompositor->m_windowFocusHistory, [this](const auto& other) { return other.expired() || other == m_self; });
if (*PCLOSEONLASTSPECIAL && m_workspace && m_workspace->getWindows() == 0 && onSpecialWorkspace()) {
const auto PMONITOR = m_monitor.lock();
if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace == m_workspace)
@ -594,8 +598,6 @@ void CWindow::onMap() {
m_movingFromWorkspaceAlpha->setValueAndWarp(1.F);
g_pCompositor->m_windowFocusHistory.push_back(m_self);
m_reportedSize = m_pendingReportedSize;
m_animatingIn = true;
@ -629,8 +631,8 @@ void CWindow::onBorderAngleAnimEnd(WP<CBaseAnimatedVariable> pav) {
void CWindow::setHidden(bool hidden) {
m_hidden = hidden;
if (hidden && g_pCompositor->m_lastWindow == m_self)
g_pCompositor->m_lastWindow.reset();
if (hidden && Desktop::focusState()->window() == m_self)
Desktop::focusState()->window().reset();
setSuspended(hidden);
}
@ -862,7 +864,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
const auto WORKSPACE = PCURRENT->m_workspace;
const auto MODE = PCURRENT->m_fullscreenState.internal;
const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_lastWindow.lock();
const auto CURRENTISFOCUS = PCURRENT == Desktop::focusState()->window();
const auto PWINDOWSIZE = PCURRENT->m_realSize->value();
const auto PWINDOWPOS = PCURRENT->m_realPosition->value();
@ -897,7 +899,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
if (CURRENTISFOCUS)
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->rawWindowFocus(pWindow);
g_pHyprRenderer->damageWindow(pWindow);
@ -1206,6 +1208,10 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
std::unordered_map<std::string, std::string> results;
std::vector<char> buffer;
size_t needle = 0;
#if defined(__linux__)
//
std::string environFile = "/proc/" + std::to_string(PID) + "/environ";
std::ifstream ifs(environFile, std::ios::binary);
@ -1213,13 +1219,25 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
if (!ifs.good())
return {};
std::vector<char> buffer;
size_t needle = 0;
buffer.resize(512, '\0');
while (ifs.read(buffer.data() + needle, 512)) {
buffer.resize(buffer.size() + 512, '\0');
needle += 512;
}
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ENV, static_cast<int>(PID)};
size_t len = 0;
if (sysctl(mib, 4, nullptr, &len, nullptr, 0) < 0 || len == 0)
return {};
buffer.resize(len, '\0');
if (sysctl(mib, 4, buffer.data(), &len, nullptr, 0) < 0)
return {};
needle = len;
#endif
if (needle <= 1)
return {};
@ -1240,7 +1258,7 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
}
void CWindow::activate(bool force) {
if (g_pCompositor->m_lastWindow == m_self)
if (Desktop::focusState()->window() == m_self)
return;
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
@ -1262,7 +1280,7 @@ void CWindow::activate(bool force) {
if (m_isFloating)
g_pCompositor->changeWindowZOrder(m_self.lock(), true);
g_pCompositor->focusWindow(m_self.lock());
Desktop::focusState()->fullWindowFocus(m_self.lock());
warpCursor();
}
@ -1276,7 +1294,7 @@ void CWindow::onUpdateState() {
if (m_isMapped) {
const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value());
g_pCompositor->moveWindowToWorkspaceSafe(m_self.lock(), monitor->m_activeWorkspace);
g_pCompositor->setActiveMonitor(monitor);
Desktop::focusState()->rawMonitorFocus(monitor);
}
if (!m_isMapped)
@ -1311,7 +1329,7 @@ void CWindow::onUpdateMeta() {
g_pEventManager->postEvent(SHyprIPCEvent{.event = "windowtitlev2", .data = std::format("{:x},{}", rc<uintptr_t>(this), m_title)});
EMIT_HOOK_EVENT("windowTitle", m_self.lock());
if (m_self == g_pCompositor->m_lastWindow) { // if it's the active, let's post an event to update others
if (m_self == Desktop::focusState()->window()) { // if it's the active, let's post an event to update others
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = m_class + "," + m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))});
EMIT_HOOK_EVENT("activeWindow", m_self.lock());
@ -1325,7 +1343,7 @@ void CWindow::onUpdateMeta() {
if (m_class != NEWCLASS) {
m_class = NEWCLASS;
if (m_self == g_pCompositor->m_lastWindow) { // if it's the active, let's post an event to update others
if (m_self == Desktop::focusState()->window()) { // if it's the active, let's post an event to update others
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = m_class + "," + m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))});
EMIT_HOOK_EVENT("activeWindow", m_self.lock());
@ -1502,7 +1520,7 @@ PHLWINDOW CWindow::getSwallower() {
return candidates[0];
// walk up the focus history and find the last focused
for (auto const& w : g_pCompositor->m_windowFocusHistory) {
for (auto const& w : Desktop::focusState()->windowHistory()) {
if (!w)
continue;
@ -1781,7 +1799,7 @@ void CWindow::updateDecorationValues() {
setBorderColor(*RENDERDATA.borderGradient);
else {
const bool GROUPLOCKED = m_groupData.pNextWindow.lock() ? getGroupHead()->m_groupData.locked : false;
if (m_self == g_pCompositor->m_lastWindow) {
if (m_self == Desktop::focusState()->window()) {
const auto* const ACTIVECOLOR =
!m_groupData.pNextWindow.lock() ? (!m_groupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
setBorderColor(m_ruleApplicator->activeBorderColor().valueOr(*ACTIVECOLOR));
@ -1797,7 +1815,7 @@ void CWindow::updateDecorationValues() {
if (isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) {
*m_activeInactiveAlpha = m_ruleApplicator->alphaFullscreen().valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
} else {
if (m_self == g_pCompositor->m_lastWindow)
if (m_self == Desktop::focusState()->window())
*m_activeInactiveAlpha = m_ruleApplicator->alpha().valueOrDefault().applyAlpha(*PACTIVEALPHA);
else
*m_activeInactiveAlpha = m_ruleApplicator->alphaInactive().valueOrDefault().applyAlpha(*PINACTIVEALPHA);
@ -1805,7 +1823,7 @@ void CWindow::updateDecorationValues() {
// dim
float goalDim = 1.F;
if (m_self == g_pCompositor->m_lastWindow.lock() || m_ruleApplicator->noDim().valueOrDefault() || !*PDIMENABLED)
if (m_self == Desktop::focusState()->window() || m_ruleApplicator->noDim().valueOrDefault() || !*PDIMENABLED)
goalDim = 0;
else
goalDim = *PDIMSTRENGTH;
@ -1817,7 +1835,7 @@ void CWindow::updateDecorationValues() {
// shadow
if (!isX11OverrideRedirect() && !m_X11DoesntWantBorders) {
if (m_self == g_pCompositor->m_lastWindow)
if (m_self == Desktop::focusState()->window())
*m_realShadowColor = CHyprColor(*PSHADOWCOL);
else
*m_realShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != -1 ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
@ -1828,7 +1846,7 @@ void CWindow::updateDecorationValues() {
}
std::optional<double> CWindow::calculateSingleExpr(const std::string& s) {
const auto PMONITOR = m_monitor ? m_monitor : g_pCompositor->m_lastMonitor;
const auto PMONITOR = m_monitor ? m_monitor : Desktop::focusState()->monitor();
const auto CURSOR_LOCAL = g_pInputManager->getMouseCoordsInternal() - (PMONITOR ? PMONITOR->m_position : Vector2D{});
Math::CExpression expr;

View file

@ -3,6 +3,7 @@
#include "../../../helpers/Monitor.hpp"
#include "../../../Compositor.hpp"
#include "../../../managers/TokenManager.hpp"
#include "../../../desktop/state/FocusState.hpp"
using namespace Desktop;
using namespace Desktop::Rule;
@ -72,7 +73,7 @@ bool CWindowRule::matches(PHLWINDOW w, bool allowEnvLookup) {
return false;
break;
case RULE_PROP_FOCUS:
if (!engine->match(g_pCompositor->m_lastWindow == w))
if (!engine->match(Desktop::focusState()->window() == w))
return false;
break;
case RULE_PROP_GROUP:

View file

@ -18,13 +18,17 @@ CWindowRuleApplicator::CWindowRuleApplicator(PHLWINDOW w) : m_window(w) {
;
}
void CWindowRuleApplicator::resetProps(std::underlying_type_t<eRuleProperty> props, Types::eOverridePriority prio) {
std::unordered_set<CWindowRuleEffectContainer::storageType> CWindowRuleApplicator::resetProps(std::underlying_type_t<eRuleProperty> props, Types::eOverridePriority prio) {
// TODO: fucking kill me, is there a better way to do this?
std::unordered_set<CWindowRuleEffectContainer::storageType> effectsNuked;
#define UNSET(x) \
if (m_##x.second & props) { \
if (prio == Types::PRIORITY_WINDOW_RULE) \
if (prio == Types::PRIORITY_WINDOW_RULE) { \
effectsNuked.emplace(x##Effect()); \
m_##x.second &= ~props; \
} \
m_##x.first.unset(prio); \
}
@ -81,6 +85,8 @@ void CWindowRuleApplicator::resetProps(std::underlying_type_t<eRuleProperty> pro
std::erase_if(m_otherProps.props, [props](const auto& el) { return !el.second || el.second->propMask & props; });
}
return effectsNuked;
}
CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const SP<CWindowRule>& rule) {
@ -130,10 +136,8 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
break;
}
case WINDOW_RULE_EFFECT_PERSISTENT_SIZE: {
try {
m_persistentSize.first.set(std::stoi(effect), Types::PRIORITY_WINDOW_RULE);
m_persistentSize.second |= rule->getPropertiesMask();
} catch (...) { Debug::log(ERR, "CWindowRuleApplicator::applyDynamicRule: invalid rounding_power {}", effect); }
m_persistentSize.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE);
m_persistentSize.second |= rule->getPropertiesMask();
break;
}
case WINDOW_RULE_EFFECT_ANIMATION: {
@ -541,8 +545,8 @@ void CWindowRuleApplicator::readStaticRules() {
static_ = {};
std::vector<SP<IRule>> toRemove;
bool tagsWereChanged = false;
std::vector<SP<CWindowRule>> execRules;
bool tagsWereChanged = false;
for (const auto& r : ruleEngine()->rules()) {
if (r->type() != RULE_TYPE_WINDOW)
@ -553,16 +557,14 @@ void CWindowRuleApplicator::readStaticRules() {
if (!wr->matches(m_window.lock(), true))
continue;
if (wr->isExecRule()) {
execRules.emplace_back(wr);
continue;
}
applyStaticRule(wr);
const auto RES = applyDynamicRule(wr); // also apply dynamic, because we won't recheck it before layout gets data
const auto RES = applyDynamicRule(wr);
tagsWereChanged = tagsWereChanged || RES.tagsChanged;
if (wr->isExecRule())
toRemove.emplace_back(wr);
}
for (const auto& wr : toRemove) {
ruleEngine()->unregisterRule(wr);
}
// recheck some props people might wanna use for static rules.
@ -588,37 +590,20 @@ void CWindowRuleApplicator::readStaticRules() {
applyStaticRule(wr);
}
}
for (const auto& wr : execRules) {
applyStaticRule(wr);
applyDynamicRule(wr);
ruleEngine()->unregisterRule(wr);
}
}
void CWindowRuleApplicator::propertiesChanged(std::underlying_type_t<eRuleProperty> props) {
if (!m_window || !m_window->m_isMapped || m_window->isHidden())
return;
resetProps(props);
bool needsRelayout = false;
std::unordered_set<CWindowRuleEffectContainer::storageType> effectsNeedingRecheck;
std::unordered_set<SP<CWindowRule>> passedWrs;
for (const auto& r : ruleEngine()->rules()) {
if (r->type() != RULE_TYPE_WINDOW)
continue;
if (!(r->getPropertiesMask() & props))
continue;
auto wr = reinterpretPointerCast<CWindowRule>(r);
if (!wr->matches(m_window.lock()))
continue;
for (const auto& [type, eff] : wr->effects()) {
effectsNeedingRecheck.emplace(type);
}
passedWrs.emplace(std::move(wr));
}
bool needsRelayout = false;
std::unordered_set<CWindowRuleEffectContainer::storageType> effectsNeedingRecheck = resetProps(props);
for (const auto& r : ruleEngine()->rules()) {
if (r->type() != RULE_TYPE_WINDOW)
@ -629,7 +614,7 @@ void CWindowRuleApplicator::propertiesChanged(std::underlying_type_t<eRuleProper
if (!(WR->getPropertiesMask() & props) && !setsIntersect(WR->effectsSet(), effectsNeedingRecheck))
continue;
if (!std::ranges::contains(passedWrs, WR) && !WR->matches(m_window.lock()))
if (!WR->matches(m_window.lock()))
continue;
const auto RES = applyDynamicRule(WR);

View file

@ -1,6 +1,7 @@
#pragma once
#include <unordered_map>
#include <unordered_set>
#include "WindowRuleEffectContainer.hpp"
#include "../../DesktopTypes.hpp"
@ -29,10 +30,11 @@ namespace Desktop::Rule {
CWindowRuleApplicator(CWindowRuleApplicator&) = delete;
CWindowRuleApplicator(CWindowRuleApplicator&&) = delete;
void propertiesChanged(std::underlying_type_t<eRuleProperty> props);
void resetProps(std::underlying_type_t<eRuleProperty> props, Types::eOverridePriority prio = Types::PRIORITY_WINDOW_RULE);
void readStaticRules();
void applyStaticRules();
void propertiesChanged(std::underlying_type_t<eRuleProperty> props);
std::unordered_set<CWindowRuleEffectContainer::storageType> resetProps(std::underlying_type_t<eRuleProperty> props,
Types::eOverridePriority prio = Types::PRIORITY_WINDOW_RULE);
void readStaticRules();
void applyStaticRules();
// static props
struct {
@ -69,7 +71,7 @@ namespace Desktop::Rule {
} m_otherProps;
#define COMMA ,
#define DEFINE_PROP(type, name, def) \
#define DEFINE_PROP(type, name, def, eff) \
private: \
std::pair<Types::COverridableVar<type>, std::underlying_type_t<eRuleProperty>> m_##name = {def, RULE_PROP_NONE}; \
\
@ -79,54 +81,57 @@ namespace Desktop::Rule {
} \
void name##Override(const Types::COverridableVar<type>& other) { \
m_##name.first = other; \
} \
eWindowRuleEffect name##Effect() { \
return eff; \
}
// dynamic props
DEFINE_PROP(Types::SAlphaValue, alpha, Types::SAlphaValue{})
DEFINE_PROP(Types::SAlphaValue, alphaInactive, Types::SAlphaValue{})
DEFINE_PROP(Types::SAlphaValue, alphaFullscreen, Types::SAlphaValue{})
DEFINE_PROP(Types::SAlphaValue, alpha, Types::SAlphaValue{}, WINDOW_RULE_EFFECT_OPACITY)
DEFINE_PROP(Types::SAlphaValue, alphaInactive, Types::SAlphaValue{}, WINDOW_RULE_EFFECT_OPACITY)
DEFINE_PROP(Types::SAlphaValue, alphaFullscreen, Types::SAlphaValue{}, WINDOW_RULE_EFFECT_OPACITY)
DEFINE_PROP(bool, allowsInput, false)
DEFINE_PROP(bool, decorate, true)
DEFINE_PROP(bool, focusOnActivate, false)
DEFINE_PROP(bool, keepAspectRatio, false)
DEFINE_PROP(bool, nearestNeighbor, false)
DEFINE_PROP(bool, noAnim, false)
DEFINE_PROP(bool, noBlur, false)
DEFINE_PROP(bool, noDim, false)
DEFINE_PROP(bool, noFocus, false)
DEFINE_PROP(bool, noMaxSize, false)
DEFINE_PROP(bool, noShadow, false)
DEFINE_PROP(bool, noShortcutsInhibit, false)
DEFINE_PROP(bool, opaque, false)
DEFINE_PROP(bool, dimAround, false)
DEFINE_PROP(bool, RGBX, false)
DEFINE_PROP(bool, syncFullscreen, true)
DEFINE_PROP(bool, tearing, false)
DEFINE_PROP(bool, xray, false)
DEFINE_PROP(bool, renderUnfocused, false)
DEFINE_PROP(bool, noFollowMouse, false)
DEFINE_PROP(bool, noScreenShare, false)
DEFINE_PROP(bool, noVRR, false)
DEFINE_PROP(bool, persistentSize, false)
DEFINE_PROP(bool, stayFocused, false)
DEFINE_PROP(bool, allowsInput, false, WINDOW_RULE_EFFECT_ALLOWS_INPUT)
DEFINE_PROP(bool, decorate, true, WINDOW_RULE_EFFECT_DECORATE)
DEFINE_PROP(bool, focusOnActivate, false, WINDOW_RULE_EFFECT_FOCUS_ON_ACTIVATE)
DEFINE_PROP(bool, keepAspectRatio, false, WINDOW_RULE_EFFECT_KEEP_ASPECT_RATIO)
DEFINE_PROP(bool, nearestNeighbor, false, WINDOW_RULE_EFFECT_NEAREST_NEIGHBOR)
DEFINE_PROP(bool, noAnim, false, WINDOW_RULE_EFFECT_NO_ANIM)
DEFINE_PROP(bool, noBlur, false, WINDOW_RULE_EFFECT_NO_BLUR)
DEFINE_PROP(bool, noDim, false, WINDOW_RULE_EFFECT_NO_DIM)
DEFINE_PROP(bool, noFocus, false, WINDOW_RULE_EFFECT_NO_FOCUS)
DEFINE_PROP(bool, noMaxSize, false, WINDOW_RULE_EFFECT_NO_MAX_SIZE)
DEFINE_PROP(bool, noShadow, false, WINDOW_RULE_EFFECT_NO_SHADOW)
DEFINE_PROP(bool, noShortcutsInhibit, false, WINDOW_RULE_EFFECT_NO_SHORTCUTS_INHIBIT)
DEFINE_PROP(bool, opaque, false, WINDOW_RULE_EFFECT_OPAQUE)
DEFINE_PROP(bool, dimAround, false, WINDOW_RULE_EFFECT_DIM_AROUND)
DEFINE_PROP(bool, RGBX, false, WINDOW_RULE_EFFECT_FORCE_RGBX)
DEFINE_PROP(bool, syncFullscreen, true, WINDOW_RULE_EFFECT_SYNC_FULLSCREEN)
DEFINE_PROP(bool, tearing, false, WINDOW_RULE_EFFECT_IMMEDIATE)
DEFINE_PROP(bool, xray, false, WINDOW_RULE_EFFECT_XRAY)
DEFINE_PROP(bool, renderUnfocused, false, WINDOW_RULE_EFFECT_RENDER_UNFOCUSED)
DEFINE_PROP(bool, noFollowMouse, false, WINDOW_RULE_EFFECT_NO_FOLLOW_MOUSE)
DEFINE_PROP(bool, noScreenShare, false, WINDOW_RULE_EFFECT_NO_SCREEN_SHARE)
DEFINE_PROP(bool, noVRR, false, WINDOW_RULE_EFFECT_NO_VRR)
DEFINE_PROP(bool, persistentSize, false, WINDOW_RULE_EFFECT_PERSISTENT_SIZE)
DEFINE_PROP(bool, stayFocused, false, WINDOW_RULE_EFFECT_STAY_FOCUSED)
DEFINE_PROP(int, idleInhibitMode, false)
DEFINE_PROP(int, idleInhibitMode, false, WINDOW_RULE_EFFECT_IDLE_INHIBIT)
DEFINE_PROP(Hyprlang::INT, borderSize, {std::string("general:border_size") COMMA sc<Hyprlang::INT>(0) COMMA std::nullopt})
DEFINE_PROP(Hyprlang::INT, rounding, {std::string("decoration:rounding") COMMA sc<Hyprlang::INT>(0) COMMA std::nullopt})
DEFINE_PROP(Hyprlang::INT, borderSize, {std::string("general:border_size") COMMA sc<Hyprlang::INT>(0) COMMA std::nullopt}, WINDOW_RULE_EFFECT_BORDER_SIZE)
DEFINE_PROP(Hyprlang::INT, rounding, {std::string("decoration:rounding") COMMA sc<Hyprlang::INT>(0) COMMA std::nullopt}, WINDOW_RULE_EFFECT_ROUNDING)
DEFINE_PROP(Hyprlang::FLOAT, roundingPower, {std::string("decoration:rounding_power")})
DEFINE_PROP(Hyprlang::FLOAT, scrollMouse, {std::string("input:scroll_factor")})
DEFINE_PROP(Hyprlang::FLOAT, scrollTouchpad, {std::string("input:touchpad:scroll_factor")})
DEFINE_PROP(Hyprlang::FLOAT, roundingPower, {std::string("decoration:rounding_power")}, WINDOW_RULE_EFFECT_ROUNDING_POWER)
DEFINE_PROP(Hyprlang::FLOAT, scrollMouse, {std::string("input:scroll_factor")}, WINDOW_RULE_EFFECT_SCROLL_MOUSE)
DEFINE_PROP(Hyprlang::FLOAT, scrollTouchpad, {std::string("input:touchpad:scroll_factor")}, WINDOW_RULE_EFFECT_SCROLL_TOUCHPAD)
DEFINE_PROP(std::string, animationStyle, std::string(""))
DEFINE_PROP(std::string, animationStyle, std::string(""), WINDOW_RULE_EFFECT_ANIMATION)
DEFINE_PROP(Vector2D, maxSize, Vector2D{})
DEFINE_PROP(Vector2D, minSize, Vector2D{})
DEFINE_PROP(Vector2D, maxSize, Vector2D{}, WINDOW_RULE_EFFECT_MAX_SIZE)
DEFINE_PROP(Vector2D, minSize, Vector2D{}, WINDOW_RULE_EFFECT_MIN_SIZE)
DEFINE_PROP(CGradientValueData, activeBorderColor, {})
DEFINE_PROP(CGradientValueData, inactiveBorderColor, {})
DEFINE_PROP(CGradientValueData, activeBorderColor, {}, WINDOW_RULE_EFFECT_BORDER_COLOR)
DEFINE_PROP(CGradientValueData, inactiveBorderColor, {}, WINDOW_RULE_EFFECT_BORDER_COLOR)
std::vector<std::pair<std::string, std::underlying_type_t<eRuleProperty>>> m_dynamicTags;
CTagKeeper m_tagKeeper;

View file

@ -0,0 +1,330 @@
#include "FocusState.hpp"
#include "../Window.hpp"
#include "../../Compositor.hpp"
#include "../../protocols/XDGShell.hpp"
#include "../../render/Renderer.hpp"
#include "../../managers/LayoutManager.hpp"
#include "../../managers/EventManager.hpp"
#include "../../managers/HookSystemManager.hpp"
#include "../../xwayland/XSurface.hpp"
#include "../../protocols/PointerConstraints.hpp"
using namespace Desktop;
SP<CFocusState> Desktop::focusState() {
static SP<CFocusState> state = makeShared<CFocusState>();
return state;
}
Desktop::CFocusState::CFocusState() {
m_windowOpen = g_pHookSystem->hookDynamic("openWindowEarly", [this](void* self, SCallbackInfo& info, std::any data) {
auto window = std::any_cast<PHLWINDOW>(data);
addWindowToHistory(window);
});
m_windowClose = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
auto window = std::any_cast<PHLWINDOW>(data);
removeWindowFromHistory(window);
});
}
struct SFullscreenWorkspaceFocusResult {
PHLWINDOW overrideFocusWindow = nullptr;
};
static SFullscreenWorkspaceFocusResult onFullscreenWorkspaceFocusWindow(PHLWINDOW pWindow, bool forceFSCycle) {
const auto FSWINDOW = pWindow->m_workspace->getFullscreenWindow();
const auto FSMODE = pWindow->m_workspace->m_fullscreenMode;
if (pWindow == FSWINDOW)
return {}; // no conflict
if (pWindow->m_isFloating) {
// if the window is floating, just bring it to the top
pWindow->m_createdOverFullscreen = true;
g_pHyprRenderer->damageWindow(pWindow);
return {};
}
static auto PONFOCUSUNDERFS = CConfigValue<Hyprlang::INT>("misc:on_focus_under_fullscreen");
switch (*PONFOCUSUNDERFS) {
case 0:
// focus the fullscreen window instead
return {.overrideFocusWindow = FSWINDOW};
case 2:
// undo fs, unless we force a cycle
if (!forceFSCycle) {
g_pCompositor->setWindowFullscreenInternal(FSWINDOW, FSMODE_NONE);
break;
}
[[fallthrough]];
case 1:
// replace fullscreen
g_pCompositor->setWindowFullscreenInternal(FSWINDOW, FSMODE_NONE);
g_pCompositor->setWindowFullscreenInternal(pWindow, FSMODE);
break;
default: Debug::log(ERR, "Invalid misc:on_focus_under_fullscreen mode: {}", *PONFOCUSUNDERFS); break;
}
return {};
}
void CFocusState::fullWindowFocus(PHLWINDOW pWindow, SP<CWLSurfaceResource> surface, bool preserveFocusHistory, bool forceFSCycle) {
if (pWindow) {
if (!pWindow->m_workspace)
return;
const auto CURRENT_FS_MODE = pWindow->m_workspace->m_hasFullscreenWindow ? pWindow->m_workspace->m_fullscreenMode : FSMODE_NONE;
if (CURRENT_FS_MODE != FSMODE_NONE) {
const auto RESULT = onFullscreenWorkspaceFocusWindow(pWindow, forceFSCycle);
if (RESULT.overrideFocusWindow)
pWindow = RESULT.overrideFocusWindow;
}
}
static auto PMODALPARENTBLOCKING = CConfigValue<Hyprlang::INT>("general:modal_parent_blocking");
if (*PMODALPARENTBLOCKING && pWindow && pWindow->m_xdgSurface && pWindow->m_xdgSurface->m_toplevel && pWindow->m_xdgSurface->m_toplevel->anyChildModal()) {
Debug::log(LOG, "Refusing focus to window shadowed by modal dialog");
return;
}
rawWindowFocus(pWindow, surface, preserveFocusHistory);
}
void CFocusState::rawWindowFocus(PHLWINDOW pWindow, SP<CWLSurfaceResource> surface, bool preserveFocusHistory) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
if (!pWindow || !pWindow->priorityFocus()) {
if (g_pSessionLockManager->isSessionLocked()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
return;
}
if (!g_pInputManager->m_exclusiveLSes.empty()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
return;
}
}
if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
return;
g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow);
if (!pWindow || !validMapped(pWindow)) {
if (m_focusWindow.expired() && !pWindow)
return;
const auto PLASTWINDOW = m_focusWindow.lock();
m_focusWindow.reset();
if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
PLASTWINDOW->m_ruleApplicator->propertiesChanged(Rule::RULE_PROP_FOCUS);
PLASTWINDOW->updateDecorationValues();
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
}
g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr});
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
m_focusSurface.reset();
g_pInputManager->recheckIdleInhibitorStatus();
return;
}
if (pWindow->m_ruleApplicator->noFocus().valueOrDefault()) {
Debug::log(LOG, "Ignoring focus to nofocus window!");
return;
}
if (m_focusWindow.lock() == pWindow && g_pSeatManager->m_state.keyboardFocus == surface && g_pSeatManager->m_state.keyboardFocus)
return;
if (pWindow->m_pinned)
pWindow->m_workspace = m_focusMonitor->m_activeWorkspace;
const auto PMONITOR = pWindow->m_monitor.lock();
if (!pWindow->m_workspace || !pWindow->m_workspace->isVisible()) {
const auto PWORKSPACE = pWindow->m_workspace;
// This is to fix incorrect feedback on the focus history.
PWORKSPACE->m_lastFocusedWindow = pWindow;
if (m_focusMonitor->m_activeWorkspace)
PWORKSPACE->rememberPrevWorkspace(m_focusMonitor->m_activeWorkspace);
if (PWORKSPACE->m_isSpecialWorkspace)
m_focusMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor
else if (PMONITOR)
PMONITOR->changeWorkspace(PWORKSPACE, false, true);
// changeworkspace already calls focusWindow
return;
}
const auto PLASTWINDOW = m_focusWindow.lock();
m_focusWindow = pWindow;
/* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which
window focuses are "via keybinds" and which ones aren't. */
if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace != pWindow->m_workspace && !pWindow->m_pinned && !*PSPECIALFALLTHROUGH)
PMONITOR->setSpecialWorkspace(nullptr);
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
PLASTWINDOW->m_ruleApplicator->propertiesChanged(Rule::RULE_PROP_FOCUS);
PLASTWINDOW->updateDecorationValues();
if (!pWindow->m_isX11 || !pWindow->isX11OverrideRedirect())
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
}
const auto PWINDOWSURFACE = surface ? surface : pWindow->m_wlSurface->resource();
rawSurfaceFocus(PWINDOWSURFACE, pWindow);
g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
pWindow->m_ruleApplicator->propertiesChanged(Rule::RULE_PROP_FOCUS);
pWindow->onFocusAnimUpdate();
pWindow->updateDecorationValues();
if (pWindow->m_isUrgent)
pWindow->m_isUrgent = false;
// Send an event
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = pWindow->m_class + "," + pWindow->m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(pWindow.get()))});
EMIT_HOOK_EVENT("activeWindow", pWindow);
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
g_pInputManager->recheckIdleInhibitorStatus();
if (!preserveFocusHistory) {
// move to front of the window history
moveWindowToLatestInHistory(pWindow);
}
if (*PFOLLOWMOUSE == 0)
g_pInputManager->sendMotionEventsToFocused();
if (pWindow->m_groupData.pNextWindow)
pWindow->deactivateGroupMembers();
}
void CFocusState::rawSurfaceFocus(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindowOwner) {
if (g_pSeatManager->m_state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->m_state.keyboardFocus == pWindowOwner->m_wlSurface->resource()))
return; // Don't focus when already focused on this.
if (g_pSessionLockManager->isSessionLocked() && pSurface && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
return;
if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(pSurface)) {
Debug::log(LOG, "surface {:x} won't receive kb focus because grab rejected it", rc<uintptr_t>(pSurface.get()));
return;
}
const auto PLASTSURF = m_focusSurface.lock();
// Unfocus last surface if should
if (m_focusSurface && !pWindowOwner)
g_pXWaylandManager->activateSurface(m_focusSurface.lock(), false);
if (!pSurface) {
g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""});
EMIT_HOOK_EVENT("keyboardFocus", SP<CWLSurfaceResource>{nullptr});
m_focusSurface.reset();
return;
}
if (g_pSeatManager->m_keyboard)
g_pSeatManager->setKeyboardFocus(pSurface);
if (pWindowOwner)
Debug::log(LOG, "Set keyboard focus to surface {:x}, with {}", rc<uintptr_t>(pSurface.get()), pWindowOwner);
else
Debug::log(LOG, "Set keyboard focus to surface {:x}", rc<uintptr_t>(pSurface.get()));
g_pXWaylandManager->activateSurface(pSurface, true);
m_focusSurface = pSurface;
EMIT_HOOK_EVENT("keyboardFocus", pSurface);
const auto SURF = CWLSurface::fromResource(pSurface);
const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
if (OLDSURF && OLDSURF->constraint())
OLDSURF->constraint()->deactivate();
if (SURF && SURF->constraint())
SURF->constraint()->activate();
}
void CFocusState::rawMonitorFocus(PHLMONITOR pMonitor) {
if (m_focusMonitor == pMonitor)
return;
if (!pMonitor) {
m_focusMonitor.reset();
return;
}
const auto PWORKSPACE = pMonitor->m_activeWorkspace;
const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_id) : std::to_string(WORKSPACE_INVALID);
const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_name : "?";
g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmon", .data = pMonitor->m_name + "," + WORKSPACE_NAME});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmonv2", .data = pMonitor->m_name + "," + WORKSPACE_ID});
EMIT_HOOK_EVENT("focusedMon", pMonitor);
m_focusMonitor = pMonitor;
}
SP<CWLSurfaceResource> CFocusState::surface() {
return m_focusSurface.lock();
}
PHLWINDOW CFocusState::window() {
return m_focusWindow.lock();
}
PHLMONITOR CFocusState::monitor() {
return m_focusMonitor.lock();
}
const std::vector<PHLWINDOWREF>& CFocusState::windowHistory() {
return m_windowFocusHistory;
}
void CFocusState::removeWindowFromHistory(PHLWINDOW w) {
std::erase_if(m_windowFocusHistory, [&w](const auto& e) { return !e || e == w; });
}
void CFocusState::addWindowToHistory(PHLWINDOW w) {
m_windowFocusHistory.emplace_back(w);
}
void CFocusState::moveWindowToLatestInHistory(PHLWINDOW w) {
const auto HISTORYPIVOT = std::ranges::find_if(m_windowFocusHistory, [&w](const auto& other) { return other.lock() == w; });
if (HISTORYPIVOT == m_windowFocusHistory.end())
Debug::log(TRACE, "CFocusState: {} has no pivot in history, ignoring request to move to latest", w);
else
std::rotate(m_windowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
}

View file

@ -0,0 +1,43 @@
#pragma once
#include "../DesktopTypes.hpp"
#include "../../SharedDefs.hpp"
class CWLSurfaceResource;
namespace Desktop {
class CFocusState {
public:
CFocusState();
~CFocusState() = default;
CFocusState(CFocusState&&) = delete;
CFocusState(CFocusState&) = delete;
CFocusState(const CFocusState&) = delete;
void fullWindowFocus(PHLWINDOW w, SP<CWLSurfaceResource> surface = nullptr, bool preserveFocusHistory = false, bool forceFSCycle = false);
void rawWindowFocus(PHLWINDOW w, SP<CWLSurfaceResource> surface = nullptr, bool preserveFocusHistory = false);
void rawSurfaceFocus(SP<CWLSurfaceResource> s, PHLWINDOW pWindowOwner = nullptr);
void rawMonitorFocus(PHLMONITOR m);
SP<CWLSurfaceResource> surface();
PHLWINDOW window();
PHLMONITOR monitor();
const std::vector<PHLWINDOWREF>& windowHistory();
void addWindowToHistory(PHLWINDOW w);
private:
void removeWindowFromHistory(PHLWINDOW w);
void moveWindowToLatestInHistory(PHLWINDOW w);
WP<CWLSurfaceResource> m_focusSurface;
PHLWINDOWREF m_focusWindow;
PHLMONITORREF m_focusMonitor;
std::vector<PHLWINDOWREF> m_windowFocusHistory; // first element is the most recently focused
SP<HOOK_CALLBACK_FN> m_windowOpen, m_windowClose;
};
SP<CFocusState> focusState();
};

View file

@ -3,7 +3,8 @@
#include <cstdint>
#include <type_traits>
#include <any>
#include <map>
#include <ranges>
#include <algorithm>
#include "../../config/ConfigValue.hpp"
namespace Desktop::Types {
@ -25,6 +26,8 @@ namespace Desktop::Types {
PRIORITY_WORKSPACE_RULE,
PRIORITY_WINDOW_RULE,
PRIORITY_SET_PROP,
PRIORITY_END,
};
template <typename T>
@ -56,11 +59,11 @@ namespace Desktop::Types {
if (this == &other)
return *this;
for (auto const& value : other.m_values) {
for (size_t i = 0; i < PRIORITY_END; ++i) {
if constexpr (Extended && !std::is_same_v<T, bool>)
m_values[value.first] = clampOptional(value.second, m_minValue, m_maxValue);
m_values[i] = clampOptional(*other.m_values[i], m_minValue, m_maxValue);
else
m_values[value.first] = value.second;
m_values[i] = other.m_values[i];
}
return *this;
@ -71,18 +74,19 @@ namespace Desktop::Types {
}
void unset(eOverridePriority priority) {
m_values.erase(priority);
m_values[priority] = std::nullopt;
}
bool hasValue() const {
return !m_values.empty();
return std::ranges::any_of(m_values, [](const auto& e) { return e.has_value(); });
}
T value() const {
if (!m_values.empty())
return std::prev(m_values.end())->second;
else
throw std::bad_optional_access();
for (const auto& v : m_values | std::ranges::views::reverse) {
if (v)
return *v;
}
throw std::bad_optional_access();
}
T valueOr(T const& other) const {
@ -115,10 +119,12 @@ namespace Desktop::Types {
}
eOverridePriority getPriority() const {
if (!m_values.empty())
return std::prev(m_values.end())->first;
else
throw std::bad_optional_access();
for (int i = PRIORITY_END - 1; i >= 0; --i) {
if (m_values[i])
return sc<eOverridePriority>(i);
}
throw std::bad_optional_access();
}
void increment(T const& other, eOverridePriority priority) {
@ -143,11 +149,11 @@ namespace Desktop::Types {
}
private:
std::map<eOverridePriority, T> m_values;
std::optional<T> m_defaultValue; // used for toggling, so required for bool
std::optional<T> m_minValue;
std::optional<T> m_maxValue;
std::any m_configValue; // only there for select variables
std::array<std::optional<T>, PRIORITY_END> m_values;
std::optional<T> m_defaultValue; // used for toggling, so required for bool
std::optional<T> m_minValue;
std::optional<T> m_maxValue;
std::any m_configValue; // only there for select variables
};
}

View file

@ -20,6 +20,7 @@
#include "managers/animation/DesktopAnimationManager.hpp"
#include "managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "../managers/animation/AnimationManager.hpp"
@ -57,13 +58,13 @@ void Events::listener_mapWindow(void* owner, void* data) {
static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:new_window_takes_over_fullscreen");
static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:on_focus_under_fullscreen");
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
auto PMONITOR = g_pCompositor->m_lastMonitor.lock();
if (!g_pCompositor->m_lastMonitor) {
g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({}));
PMONITOR = g_pCompositor->m_lastMonitor.lock();
auto PMONITOR = Desktop::focusState()->monitor();
if (!Desktop::focusState()->monitor()) {
Desktop::focusState()->rawMonitorFocus(g_pCompositor->getMonitorFromVector({}));
PMONITOR = Desktop::focusState()->monitor();
}
auto PWORKSPACE = PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace;
PWINDOW->m_monitor = PMONITOR;
@ -323,7 +324,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
else if (PMONITOR->activeWorkspaceID() != requestedWorkspaceID && !PWINDOW->m_noInitialFocus)
g_pKeybindManager->m_dispatchers["workspace"](requestedWorkspaceName);
PMONITOR = g_pCompositor->m_lastMonitor.lock();
PMONITOR = Desktop::focusState()->monitor();
}
requestedFSMonitor = MONITOR_INVALID;
@ -368,6 +369,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// emit the IPC event before the layout might focus the window to avoid a focus event first
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", PWINDOW, PWORKSPACE->m_name, PWINDOW->m_class, PWINDOW->m_title)});
EMIT_HOOK_EVENT("openWindowEarly", PWINDOW);
if (PWINDOW->m_isFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
@ -423,7 +425,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_pseudoSize = PWINDOW->m_realSize->goal() - Vector2D(10, 10);
}
const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_lastWindow.lock();
const auto PFOCUSEDWINDOWPREV = Desktop::focusState()->window();
if (PWINDOW->m_ruleApplicator->allowsInput().valueOrDefault()) { // if default value wasn't set to false getPriority() would throw an exception
PWINDOW->m_ruleApplicator->noFocusOverride(Desktop::Types::COverridableVar(false, PWINDOW->m_ruleApplicator->allowsInput().getPriority()));
@ -433,7 +435,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// check LS focus grab
const auto PFORCEFOCUS = g_pCompositor->getForceFocus();
const auto PLSFROMFOCUS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock());
const auto PLSFROMFOCUS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
if (PLSFROMFOCUS && PLSFROMFOCUS->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
PWINDOW->m_noInitialFocus = true;
@ -449,7 +451,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (!PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() && !PWINDOW->m_noInitialFocus &&
(!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_isX11 && PWINDOW->m_xwaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) &&
!g_pInputManager->isConstrained()) {
g_pCompositor->focusWindow(PWINDOW);
Desktop::focusState()->fullWindowFocus(PWINDOW);
PWINDOW->m_activeInactiveAlpha->setValueAndWarp(*PACTIVEALPHA);
PWINDOW->m_dimPercent->setValueAndWarp(PWINDOW->m_ruleApplicator->noDim().valueOrDefault() ? 0.f : *PDIMSTRENGTH);
} else {
@ -488,10 +490,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (workspaceSilent) {
if (validMapped(PFOCUSEDWINDOWPREV)) {
g_pCompositor->focusWindow(PFOCUSEDWINDOWPREV);
Desktop::focusState()->rawWindowFocus(PFOCUSEDWINDOWPREV);
PFOCUSEDWINDOWPREV->updateWindowDecos(); // need to for some reason i cba to find out why
} else if (!PFOCUSEDWINDOWPREV)
g_pCompositor->focusWindow(nullptr);
Desktop::focusState()->rawWindowFocus(nullptr);
}
// swallow
@ -601,10 +603,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
bool wasLastWindow = false;
if (PWINDOW == g_pCompositor->m_lastWindow.lock()) {
if (PWINDOW == Desktop::focusState()->window()) {
wasLastWindow = true;
g_pCompositor->m_lastWindow.reset();
g_pCompositor->m_lastFocus.reset();
Desktop::focusState()->window().reset();
Desktop::focusState()->surface().reset();
g_pInputManager->releaseAllMouseButtons();
}
@ -636,8 +638,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
Debug::log(LOG, "On closed window, new focused candidate is {}", PWINDOWCANDIDATE);
if (PWINDOWCANDIDATE != g_pCompositor->m_lastWindow.lock() && PWINDOWCANDIDATE) {
g_pCompositor->focusWindow(PWINDOWCANDIDATE);
if (PWINDOWCANDIDATE != Desktop::focusState()->window() && PWINDOWCANDIDATE) {
Desktop::focusState()->fullWindowFocus(PWINDOWCANDIDATE);
if (*PEXITRETAINSFS && CURRENTWINDOWFSSTATE)
g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE);
}
@ -648,7 +650,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
g_pInputManager->sendMotionEventsToFocused();
// CWindow::onUnmap will remove this window's active status, but we can't really do it above.
if (PWINDOW == g_pCompositor->m_lastWindow.lock() || !g_pCompositor->m_lastWindow.lock()) {
if (PWINDOW == Desktop::focusState()->window() || !Desktop::focusState()->window()) {
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr});
@ -751,9 +753,9 @@ void Events::listener_destroyWindow(void* owner, void* data) {
Debug::log(LOG, "{:c} destroyed, queueing.", PWINDOW);
if (PWINDOW == g_pCompositor->m_lastWindow.lock()) {
g_pCompositor->m_lastWindow.reset();
g_pCompositor->m_lastFocus.reset();
if (PWINDOW == Desktop::focusState()->window()) {
Desktop::focusState()->window().reset();
Desktop::focusState()->surface().reset();
}
PWINDOW->m_wlSurface->unassign();
@ -786,17 +788,17 @@ void Events::listener_activateX11(void* owner, void* data) {
Debug::log(LOG, "Unmanaged X11 {} requests activate", PWINDOW);
if (g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->getPID() != PWINDOW->getPID())
if (Desktop::focusState()->window() && Desktop::focusState()->window()->getPID() != PWINDOW->getPID())
return;
if (!PWINDOW->m_xwaylandSurface->wantsFocus())
return;
g_pCompositor->focusWindow(PWINDOW);
Desktop::focusState()->fullWindowFocus(PWINDOW);
return;
}
if (PWINDOW == g_pCompositor->m_lastWindow.lock() || (PWINDOW->m_suppressedEvents & SUPPRESS_ACTIVATE))
if (PWINDOW == Desktop::focusState()->window() || (PWINDOW->m_suppressedEvents & SUPPRESS_ACTIVATE))
return;
PWINDOW->activate();

View file

@ -3,7 +3,7 @@
#include <array>
// clang-format off
constexpr std::array<const char*, 35> CURSOR_SHAPE_NAMES = {
constexpr std::array<const char*, 37> CURSOR_SHAPE_NAMES = {
"invalid",
"default",
"context-menu",
@ -39,5 +39,7 @@ constexpr std::array<const char*, 35> CURSOR_SHAPE_NAMES = {
"all-scroll",
"zoom-in",
"zoom-out",
"dnd-ask",
"all-resize"
};
// clang-format on

View file

@ -3,6 +3,7 @@
#include <algorithm>
#include "../Compositor.hpp"
#include "../managers/TokenManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "Monitor.hpp"
#include "../config/ConfigManager.hpp"
#include "fs/FsUtils.hpp"
@ -146,7 +147,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else if (in.starts_with("empty")) {
const bool same_mon = in.substr(5).contains("m");
const bool next = in.substr(5).contains("n");
if ((same_mon || next) && !g_pCompositor->m_lastMonitor) {
if ((same_mon || next) && !Desktop::focusState()->monitor()) {
Debug::log(ERR, "Empty monitor workspace on monitor null!");
return {WORKSPACE_INVALID};
}
@ -155,12 +156,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
if (same_mon) {
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor);
if (PMONITOR && (PMONITOR->m_id != g_pCompositor->m_lastMonitor->m_id))
if (PMONITOR && (PMONITOR->m_id != Desktop::focusState()->monitor()->m_id))
invalidWSes.insert(rule.workspaceId);
}
}
WORKSPACEID id = next ? g_pCompositor->m_lastMonitor->activeWorkspaceID() : 0;
WORKSPACEID id = next ? Desktop::focusState()->monitor()->activeWorkspaceID() : 0;
while (++id < LONG_MAX) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
if (!invalidWSes.contains(id) && (!PWORKSPACE || PWORKSPACE->getWindows() == 0)) {
@ -169,10 +170,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
}
}
} else if (in.starts_with("prev")) {
if (!g_pCompositor->m_lastMonitor)
if (!Desktop::focusState()->monitor())
return {WORKSPACE_INVALID};
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!valid(PWORKSPACE))
return {WORKSPACE_INVALID};
@ -191,12 +192,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
return {PLASTWORKSPACE->m_id, PLASTWORKSPACE->m_name};
} else if (in == "next") {
if (!g_pCompositor->m_lastMonitor || !g_pCompositor->m_lastMonitor->m_activeWorkspace) {
if (!Desktop::focusState()->monitor() || !Desktop::focusState()->monitor()->m_activeWorkspace) {
Debug::log(ERR, "no active monitor or workspace for 'next'");
return {WORKSPACE_INVALID};
}
auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
WORKSPACEID nextId = PCURRENTWORKSPACE->m_id + 1;
@ -209,7 +210,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else {
if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) {
bool absolute = in[1] == '~';
if (!g_pCompositor->m_lastMonitor) {
if (!Desktop::focusState()->monitor()) {
Debug::log(ERR, "Relative monitor workspace on monitor null!");
return {WORKSPACE_INVALID};
}
@ -227,14 +228,14 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
// Collect all the workspaces we can't jump to.
for (auto const& ws : g_pCompositor->getWorkspaces()) {
if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor)) {
if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor())) {
// Can't jump to this workspace
invalidWSes.insert(ws->m_id);
}
}
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor);
if (!PMONITOR || PMONITOR->m_id == g_pCompositor->m_lastMonitor->m_id) {
if (!PMONITOR || PMONITOR->m_id == Desktop::focusState()->monitor()->m_id) {
// Can't be invalid
continue;
}
@ -245,7 +246,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
// Prepare all named workspaces in case when we need them
std::vector<WORKSPACEID> namedWSes;
for (auto const& ws : g_pCompositor->getWorkspaces()) {
if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor) || ws->m_id >= 0)
if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor()) || ws->m_id >= 0)
continue;
namedWSes.push_back(ws->m_id);
@ -272,7 +273,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else {
// Just take a blind guess at where we'll probably end up
WORKSPACEID activeWSID = g_pCompositor->m_lastMonitor->m_activeWorkspace ? g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id : 1;
WORKSPACEID activeWSID = Desktop::focusState()->monitor()->m_activeWorkspace ? Desktop::focusState()->monitor()->m_activeWorkspace->m_id : 1;
WORKSPACEID predictedWSID = activeWSID + remains;
int remainingWSes = 0;
char walkDir = in[1];
@ -371,7 +372,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
bool onAllMonitors = in[0] == 'e';
bool absolute = in[1] == '~';
if (!g_pCompositor->m_lastMonitor) {
if (!Desktop::focusState()->monitor()) {
Debug::log(ERR, "Relative monitor workspace on monitor null!");
return {WORKSPACE_INVALID};
}
@ -389,7 +390,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
std::vector<WORKSPACEID> validWSes;
for (auto const& ws : g_pCompositor->getWorkspaces()) {
if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor && !onAllMonitors))
if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor() && !onAllMonitors))
continue;
validWSes.push_back(ws->m_id);
@ -414,7 +415,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
// get the current item
WORKSPACEID activeWSID = g_pCompositor->m_lastMonitor->m_activeWorkspace ? g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id : 1;
WORKSPACEID activeWSID = Desktop::focusState()->monitor()->m_activeWorkspace ? Desktop::focusState()->monitor()->m_activeWorkspace->m_id : 1;
for (ssize_t i = 0; i < sc<ssize_t>(validWSes.size()); i++) {
if (validWSes[i] == activeWSID) {
currentItem = i;
@ -437,8 +438,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_name;
} else {
if (in[0] == '+' || in[0] == '-') {
if (g_pCompositor->m_lastMonitor) {
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_lastMonitor->activeWorkspaceID());
if (Desktop::focusState()->monitor()) {
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, Desktop::focusState()->monitor()->activeWorkspaceID());
if (!PLUSMINUSRESULT.has_value())
return {WORKSPACE_INVALID};

View file

@ -31,6 +31,7 @@
#include "sync/SyncTimeline.hpp"
#include "time/Time.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include <aquamarine/output/Output.hpp>
#include "debug/Log.hpp"
#include "debug/HyprNotificationOverlay.hpp"
@ -298,8 +299,8 @@ void CMonitor::onConnect(bool noRule) {
if (!m_activeMonitorRule.mirrorOf.empty())
setMirror(m_activeMonitorRule.mirrorOf);
if (!g_pCompositor->m_lastMonitor) // set the last monitor if it isn't set yet
g_pCompositor->setActiveMonitor(m_self.lock());
if (!Desktop::focusState()->monitor()) // set the last monitor if it isn't set yet
Desktop::focusState()->rawMonitorFocus(m_self.lock());
g_pHyprRenderer->arrangeLayersForMonitor(m_id);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
@ -310,7 +311,7 @@ void CMonitor::onConnect(bool noRule) {
// verify last mon valid
bool found = false;
for (auto const& m : g_pCompositor->m_monitors) {
if (m == g_pCompositor->m_lastMonitor) {
if (m == Desktop::focusState()->monitor()) {
found = true;
break;
}
@ -330,7 +331,7 @@ void CMonitor::onConnect(bool noRule) {
Debug::log(LOG, "Monitor {} was not on any workspace", m_name);
if (!found)
g_pCompositor->setActiveMonitor(m_self.lock());
Desktop::focusState()->rawMonitorFocus(m_self.lock());
g_pCompositor->scheduleFrameForMonitor(m_self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
@ -437,9 +438,9 @@ void CMonitor::onDisconnect(bool destroy) {
g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
}
} else {
g_pCompositor->m_lastFocus.reset();
g_pCompositor->m_lastWindow.reset();
g_pCompositor->m_lastMonitor.reset();
Desktop::focusState()->surface().reset();
Desktop::focusState()->window().reset();
Desktop::focusState()->monitor().reset();
}
if (m_activeWorkspace)
@ -453,8 +454,8 @@ void CMonitor::onDisconnect(bool destroy) {
if (!m_state.commit())
Debug::log(WARN, "state.commit() failed in CMonitor::onDisconnect");
if (g_pCompositor->m_lastMonitor == m_self)
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
if (Desktop::focusState()->monitor() == m_self)
Desktop::focusState()->rawMonitorFocus(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
if (g_pHyprRenderer->m_mostHzMonitor == m_self) {
int mostHz = 0;
@ -1203,7 +1204,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
g_pCompositor->scheduleMonitorStateRecheck();
g_pCompositor->setActiveMonitor(g_pCompositor->m_monitors.front());
Desktop::focusState()->rawMonitorFocus(g_pCompositor->m_monitors.front());
// Software lock mirrored monitor
g_pPointerManager->lockSoftwareForMonitor(PMIRRORMON);
@ -1286,8 +1287,8 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
w->moveToWorkspace(pWorkspace);
}
if (!noFocus && !g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace &&
!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
if (!noFocus && !Desktop::focusState()->monitor()->m_activeSpecialWorkspace &&
!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
auto pWindow = pWorkspace->m_hasFullscreenWindow ? pWorkspace->getFullscreenWindow() : pWorkspace->getLastFocusedWindow();
@ -1302,7 +1303,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
pWindow = pWorkspace->getFirstWindow();
}
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->fullWindowFocus(pWindow);
}
if (!noMouseMove)
@ -1361,9 +1362,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
if (!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
if (!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
if (const auto PLAST = m_activeWorkspace->getLastFocusedWindow(); PLAST)
g_pCompositor->focusWindow(PLAST);
Desktop::focusState()->fullWindowFocus(PLAST);
else
g_pInputManager->refocus();
}
@ -1443,9 +1444,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
if (!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
if (!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
if (const auto PLAST = pWorkspace->getLastFocusedWindow(); PLAST)
g_pCompositor->focusWindow(PLAST);
Desktop::focusState()->fullWindowFocus(PLAST);
else
g_pInputManager->refocus();
}
@ -1553,7 +1554,7 @@ uint32_t CMonitor::isSolitaryBlocked(bool full) {
return reasons;
}
if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == m_self) {
if (g_pHyprError->active() && Desktop::focusState()->monitor() == m_self) {
reasons |= SC_ERRORBAR;
if (!full)
return reasons;

View file

@ -7,6 +7,7 @@
#include "../managers/animation/AnimationManager.hpp"
#include "../render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include <hyprutils/utils/ScopeGuard.hpp>
using namespace Hyprutils::Animation;
@ -18,7 +19,7 @@ CHyprError::CHyprError() {
if (!m_isCreated)
return;
g_pHyprRenderer->damageMonitor(g_pCompositor->m_lastMonitor.lock());
g_pHyprRenderer->damageMonitor(Desktop::focusState()->monitor());
m_monitorChanged = true;
});

View file

@ -377,9 +377,9 @@ I18n::CI18nEngine::CI18nEngine() {
huEngine->registerEntry("fr_FR", TXT_KEY_ANR_PROP_UNKNOWN, "(inconnu)");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "Une application <b>{app}</b> demande une autorisation inconnue.");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Une application <b>{app}</b> tente de capturer votre écran.\n\nVoulez-vous l'y autoriser?");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "Une application <b>{app}</b> tente de charger un module : <b>{plugin}</b>.\n\nVoulez-vous l'y autoriser?");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "Un nouveau clavier a été détecté : <b>{keyboard}</b>.\n\nVouslez-vous l'autoriser à fonctioner?");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Une application <b>{app}</b> tente de capturer votre écran.\n\nVoulez-vous l'autoriser?");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "Une application <b>{app}</b> tente de charger un module : <b>{plugin}</b>.\n\nVoulez-vous l'autoriser?");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "Un nouveau clavier a été détecté : <b>{keyboard}</b>.\n\nVoulez-vous l'autoriser à fonctionner?");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(inconnu)");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_TITLE, "Demande d'autorisation");
huEngine->registerEntry("fr_FR", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Astuce: vous pouvez définir des règles persistantes dans le fichier de configuration de Hyprland.");
@ -393,7 +393,7 @@ I18n::CI18nEngine::CI18nEngine() {
"Votre variable d'environnement XDG_CURRENT_DESKTOP semble être gérée de manière externe, et sa valeur actuelle est {value}.\nCela peut provoquer des "
"problèmes si ce n'est pas intentionnel.");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_NO_GUIUTILS,
"Vous système n'a pas hyprland-guiutils installé. C'est une dépendance d'éxécution pour certains dialogues. Envisagez de l'installer.");
"Votre système n'a pas hyprland-guiutils installé. C'est une dépendance d'éxécution pour certains dialogues. Envisagez de l'installer.");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
int assetsNo = std::stoi(vars.at("count"));
if (assetsNo <= 1)
@ -403,7 +403,7 @@ I18n::CI18nEngine::CI18nEngine() {
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
"Votre disposition d'écrans est incorrecte. Le moniteur {name} chevauche un ou plusieurs autres.\nVeuillez consulter le wiki (page Moniteurs) pour"
"en savoir plus. Cela <b>causera</> des problèmes.");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Le moniteur {name} n'a pu appliquer aucun des modes demandés, retour au mode {mode}.");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Le moniteur {name} n'a pu appliquer les modes demandés, retour au mode {mode}.");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "Échelle invalide pour le moniteur {name}: {scale}. Utilisation de l'échelle suggérée: {fixed_scale}.");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Échec du chargement du module {name} : {error}");
huEngine->registerEntry("fr_FR", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "Le rechargement du shader CM a échoué, retour aux formats rgba/rgbx");
@ -466,6 +466,48 @@ I18n::CI18nEngine::CI18nEngine() {
huEngine->registerEntry("hi_IN", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CM शेडर रीलोड विफल हुआ, rgba/rgbx पर वापस जा रहा है।");
huEngine->registerEntry("hi_IN", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "मॉनिटर {name}: वाइड कलर गैम सक्षम है लेकिन डिस्प्ले 10-बिट मोड में नहीं है।");
// hr_HR (Croatian)
huEngine->registerEntry("hr_HR", TXT_KEY_ANR_TITLE, "Aplikacija ne reagira");
huEngine->registerEntry("hr_HR", TXT_KEY_ANR_CONTENT, "Aplikacija {title} - {class} ne reagira.\nŠto želiš napraviti s njom?");
huEngine->registerEntry("hr_HR", TXT_KEY_ANR_OPTION_TERMINATE, "Zaustavi");
huEngine->registerEntry("hr_HR", TXT_KEY_ANR_OPTION_WAIT, "Pričekaj");
huEngine->registerEntry("hr_HR", TXT_KEY_ANR_PROP_UNKNOWN, "(nepoznato)");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "Aplikacija <b>{app}</b> zahtijeva nepoznatu dozvolu.");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Aplikacija <b>{app}</b> pokušava snimati vaš zaslon.\n\nŽeliš li dopustiti?");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "Aplikacija <b>{app}</b> pokušava učitati dodatak: <b>{plugin}</b>.\n\nŽeliš li dopustiti?");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "Otkrivena je nova tipkovnica: <b>{keyboard}</b>.\n\nŽeliš li omogućiti njen rad?");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(nepoznato)");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_TITLE, "Zahtjev za dozvolu");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Savjet: za ovo možeš postaviti trajna pravila u Hyprland konfiguracijskoj datoteci.");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_ALLOW, "Dozvoli");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "Dozvoli i zapamti");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_ALLOW_ONCE, "Dozvoli samo ovaj put");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_DENY, "Uskrati");
huEngine->registerEntry("hr_HR", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "Nepoznata aplikacija (ID wayland klijenta {wayland_id})");
huEngine->registerEntry(
"hr_HR", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
"Izgleda da je tvoja XDG_CURRENT_DESKTOP okolina vanjski upravljana te je trenutna vrijednost {value}.\nOvo može izazvati problem, osim ako je namjerno.");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_NO_GUIUTILS,
"Na tvojem sustavu nije instaliran hyprland-guiutils. Ovo je ovisnost tijekom pokretanja nekih dijaloga. Preporučeno je da je instaliraš.");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
int assetsNo = std::stoi(vars.at("count"));
if (assetsNo % 10 <= 1 && assetsNo % 100 != 11)
return "Hyprland nije uspio učitati {count} neophodnu komponentu, krivi pakera svoje distribucije za loš posao pakiranja!";
else if (assetsNo % 10 <= 4 && assetsNo % 100 > 14)
return "Hyprland nije uspio učitati {count} neophodne komponente, krivi pakera svoje distribucije za loš posao pakiranja!";
return "Hyprland nije uspio učitati {count} neophodnih komponenata, krivi pakera svoje distribucije za loš posao pakiranja!";
});
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
"Raspored tvojih monitora je krivo postavljen. Monitor {name} preklapa se s ostalim monitorom/ima u rasporedu.\nProvjeri wiki (Monitors stranicu) za "
"više informacija. Ovo <b>hoće</b> izazvati probleme.");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Monitor {name} nije uspio odrediti zatražene načine rada, povratak na zadani način rada: {mode}.");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "Nevažeći razmjer proslijeđen monitoru {name}: {scale}, koristi se predloženi razmjer: {fixed_scale}");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Učitavanje dodatka {name} nije uspjelo: {error}");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "Ponovno učitavanje CM shadera nije uspjelo, povratak na zadano: rgba/rgbx.");
huEngine->registerEntry("hr_HR", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Monitor {name}: široki raspon boja je omogućen, ali ekran nije u 10-bitnom načinu rada.");
// it_IT (Italian)
huEngine->registerEntry("it_IT", TXT_KEY_ANR_TITLE, "L'applicazione non risponde");
huEngine->registerEntry("it_IT", TXT_KEY_ANR_CONTENT, "Un'applicazione {title} - {class} non risponde.\nCosa vuoi fare?");
@ -537,6 +579,45 @@ I18n::CI18nEngine::CI18nEngine() {
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CMシェーダーのリロード失敗、rgba/rgbxを使いました。");
huEngine->registerEntry("ja_JP", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "画面{name}広い色域は設定していますけど、画面は10ビットモードに設定されていません。");
// lv_LV (Latvian)
huEngine->registerEntry("lv_LV", TXT_KEY_ANR_TITLE, "Lietotne nereaģē");
huEngine->registerEntry("lv_LV", TXT_KEY_ANR_CONTENT, "Lietotne {title} - {class} nereaģē.\nKo jūs vēlaties darīt?");
huEngine->registerEntry("lv_LV", TXT_KEY_ANR_OPTION_TERMINATE, "Beigt procesu");
huEngine->registerEntry("lv_LV", TXT_KEY_ANR_OPTION_WAIT, "Gaidīt");
huEngine->registerEntry("lv_LV", TXT_KEY_ANR_PROP_UNKNOWN, "(nezināms)");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "Lietotne <b>{app}</b> pieprasa nezināmu atļauju.");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Lietotne <b>{app}</b> mēģina lasīt no jūsu ekrāna.\n\nVai vēlaties to atļaut?");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "Lietotne <b>{app}</b> mēģina ielādēt spraudni: <b>{plugin}</b>.\n\nVai vēlaties to atļaut?");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "Ir atrasta jauna tastatūra: <b>{keyboard}</b>.\n\nVai vēlaties atļaut tās darbību?");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(nezināms)");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_TITLE, "Atļaujas pieprasījums");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Padoms: Hyprland konfigurācijas failā varat arī iestatīt atļaujas.");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_ALLOW, "Atļaut");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "Atļaut un atcerēties");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_ALLOW_ONCE, "Atļaut vienreiz");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_DENY, "Aizliegt");
huEngine->registerEntry("lv_LV", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "Nezināma lietotne (Wayland klienta ID {wayland_id})");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
"Jūsu XDG_CURRENT_DESKTOP tiek ārēji pārvaldīts, tās vērtība ir {value}.\nTas var neapzināti izraisīt problēmas.");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_NO_GUIUTILS, "Jums nav instalēts hyprland-guiutils. Šī pakotne ir nepieciešama dažiem dialogiem. Apsveriet tās instalēšanu.");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
int assetsNo = std::stoi(vars.at("count"));
if (assetsNo <= 1)
return "Hyprland nevarēja ielādēt {count} būtisku resursu, vainojiet sava distro iepakotāju par sliktu iepakošanu!";
return "Hyprland nevarēja ielādēt {count} būtiskus resursus, vainojiet sava distro iepakotāju par sliktu iepakošanu!";
});
huEngine->registerEntry(
"lv_LV", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
"Jūsu monitora izkārtojums ir nepareizi iestatīts. Monitors {name} pārklājas ar citiem izkārtojumā iestatītajiem monitoriem.\nLūdzu apskatieties (Monitoru lapā),"
"lai uzzinātu vairāk. Tas <b>radīs</b> problēmas.");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Monitoram {name} neizdevās iestatīt nevienu no pieprasītajiem režīmiem, izmantojam {mode}.");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "Monitoram {name} ir nodots nederīgs mērogs: {scale}, izmantojam ieteikto mērogu: {fixed_scale}");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Nevarēja ielādēt spraudni {name}: {error}");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CM šeiderus neizdevās pārlādēt, izmantojam rgba/rgbx.");
huEngine->registerEntry("lv_LV", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Monitors {name}: Ir iespējota plaša krāsu gamma, bet displejs nav 10-bitu režīmā.");
// hu_HU (Hungarian)
huEngine->registerEntry("hu_HU", TXT_KEY_ANR_TITLE, "Az alkalmazás nem válaszol");
huEngine->registerEntry("hu_HU", TXT_KEY_ANR_CONTENT, "A(z) {title} - {class} alkalmazás nem válaszol.\nMit szeretne tenni vele?");
@ -662,6 +743,44 @@ I18n::CI18nEngine::CI18nEngine() {
huEngine->registerEntry("nb_NO", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CM shader omlading feilet, faller tilbake til rgba/rgbx.");
huEngine->registerEntry("nb_NO", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Skjerm {name}: bredt fargespekter er aktivert, men skjermen er ikke i 10-bit modus.");
// ne_NP (Nepali)
huEngine->registerEntry("ne_NP", TXT_KEY_ANR_TITLE, "एपले रिस्पन्ड गरिरहेको छैन");
huEngine->registerEntry("ne_NP", TXT_KEY_ANR_CONTENT, "{title} - {class} एपले रिस्पन्ड गरिरहेको छैन।\nयससँग के गर्न चहानुहुन्छ?");
huEngine->registerEntry("ne_NP", TXT_KEY_ANR_OPTION_TERMINATE, "टर्मिनेट गर्नुहोस्");
huEngine->registerEntry("ne_NP", TXT_KEY_ANR_OPTION_WAIT, "पर्खनुहोस्");
huEngine->registerEntry("ne_NP", TXT_KEY_ANR_PROP_UNKNOWN, "(अज्ञात)");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "<b>{app}</b> एपले अज्ञात सुविधाको अनुमति मागिरहेको छ।");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "<b>{app}</b> एपले स्क्रिन क्याप्चर गर्न खोज्दै छ।\n\nयसलाई अनुमति दिन चहानुहुन्छ?");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "<b>{app}</b> एपले एउटा प्लगिन लोड गर्न खोज्दै छ: <b>{plugin}</b>।\n\nयसलाई अनुमति दिन चहानुहुन्छ?");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "एउटा नयाँ किबोर्ड डिटेक्ट गरिएको छ: <b>{keyboard}</b>।\n\nयसलाई चल्ने अनुमति दिन चहानुहुन्छ?");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(अज्ञात)");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_TITLE, "अनुमतिको माग");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "टिप: यसको लागि पर्सिस्टेन्ट नियमहरु तपाइँले हाइपरल्यान्डको कन्फीग्युरेसन फाइलमा राख्न सक्नुहुन्छ।");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_ALLOW, "अनुमति दिनुहोस्");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "अनुमति दिनुहोस् र सम्झनुहोस्");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_ALLOW_ONCE, "एकपटक अनुमति दिनुहोस्");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_DENY, "अनुमति नदिनुहोस्");
huEngine->registerEntry("ne_NP", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "अज्ञात एप (wayland क्लाइन्ट आईडी {wayland_id})");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
"तपाईँको XDG_CURRENT_DESKTOP वातावरण बाहिरबाट व्यवस्थापन भइरहेको जस्तो देखिएको छ, अहिले {value} देखाइरहेको छ।\nजानीजानी नगरीएको भएमा यसले समस्याहरु निम्त्याउन सक्छ।");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_NO_GUIUTILS, "तपाइँको सिस्टममा hyprland-guiutils इन्सटल गरिएको छैन। केहि डायलगहरुका लागि यो रनटाइम डिपेन्डेन्सी हो। कृपया इन्सटल गर्नुहोला।");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
int assetsNo = std::stoi(vars.at("count"));
if (assetsNo <= 1)
return "हाइपरल्यान्डले एउटा अत्यावश्यक एसेट लोड गर्न सकेन, तपाइँको डिस्ट्रोको प्याकेजरको प्याकेजिङ गतिलो छैन!";
return "हाइपरल्यान्डले {count} अत्यावश्यक एसेटहरु लोड गर्न सकेन, तपाइँको डिस्ट्रोको प्याकेजरको प्याकेजिङ गतिलो छैन!";
});
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
"तपाइँको मनिटरको लेआउट गलत तरिकाले मिलाइएको छ। लेआउटमा {name} मनिटर अर्को मनिटर वा मनिटरहरुसङ्ग ओभरल्याप भएको छ।\nथप बुझ्नलाई कृपया विकिको मनिटर पेज हेर्नुहोस्।"
"यसले <b>निश्चित रुपमा</b> समस्या निम्त्याउने छ।");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "{name} मनिटरले चाहेको कुनै पनि मोड सेट गर्न सकेन, {mode} मोडमा फर्कँदै।");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "{name} मनिटरलाई अमान्य स्केल पठाइयो: {scale}, सजेस्ट गरिएको स्केल प्रयोग गर्दै: {fixed_scale}");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "{name} प्लगिन लोेड गर्न सकिएन: {error}");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "CM shader रिलोड गर्न सकिएन, rgba/rgbx मा फर्कँदै।");
huEngine->registerEntry("ne_NP", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "{name} मनिटर: wide color gamut अन छ तर डिस्प्ले 10-bit मोड मा छैन।");
// nl_NL (Dutch)
huEngine->registerEntry("nl_NL", TXT_KEY_ANR_TITLE, "Applicatie Reageert Niet");
huEngine->registerEntry("nl_NL", TXT_KEY_ANR_CONTENT, "Een applicatie {title} - {class} reageert niet.\nWat wilt u doen?");
@ -1103,6 +1222,48 @@ I18n::CI18nEngine::CI18nEngine() {
huEngine->registerEntry("uk_UA", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Помилка завантаження плагіна {name}: {error}");
huEngine->registerEntry("uk_UA", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "Не вдалося перезавантажити шейдер CM, повернення до rgba/rgbx.");
huEngine->registerEntry("uk_UA", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Монітор {name}: широка кольорова гама увімкнена, але дисплей не працює в 10-бітному режимі.");
// cs_CZ (Czech)
huEngine->registerEntry("cs_CZ", TXT_KEY_ANR_TITLE, "Aplikace Neodpovídá");
huEngine->registerEntry("cs_CZ", TXT_KEY_ANR_CONTENT, "Aplikace {title} - {class} neodpovídá.\nCo s ní chcete udělat?");
huEngine->registerEntry("cs_CZ", TXT_KEY_ANR_OPTION_TERMINATE, "Ukončit");
huEngine->registerEntry("cs_CZ", TXT_KEY_ANR_OPTION_WAIT, "Počkat");
huEngine->registerEntry("cs_CZ", TXT_KEY_ANR_PROP_UNKNOWN, "(neznámé)");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_REQUEST_UNKNOWN, "Aplikace <b>{app}</b> vyžaduje neznámé oprávnění.");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_REQUEST_SCREENCOPY, "Aplikace <b>{app}</b> se pokouší zaznamenávat vaši obrazovku.\n\nChcete jí to povolit?");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_REQUEST_PLUGIN, "Aplikace <b>{app}</b> se pokouší načíst plugin: <b>{plugin}</b>.\n\nChcete jí to povolit?");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_REQUEST_KEYBOARD, "Byla detekována nová klávesnice: <b>{keyboard}</b>.\n\nChcete jí povolit?");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_UNKNOWN_NAME, "(neznámé)");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_TITLE, "Žádost o oprávnění");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_PERSISTENCE_HINT, "Tip: pro tyto případy můžete nastavit trvalá pravidla v konfiguračním souboru Hyprland.");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_ALLOW, "Povolit");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER, "Povolit a zapamatovat");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_ALLOW_ONCE, "Povolit jednou");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_DENY, "Zamítnout");
huEngine->registerEntry("cs_CZ", TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP, "Neznámá aplikace (ID klienta Wayland {wayland_id})");
huEngine->registerEntry(
"cs_CZ", TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
"Proměnná prostředí XDG_CURRENT_DESKTOP se zdá být spravována externě a její aktuální hodnota je {value}.\nPokud to není záměr, může to způsobit problémy.");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_NO_GUIUTILS,
"V systému není nainstalován balíček hyprland-guiutils. Jedná se o závislost pro běh některých dialogových oken. Zvažte jeho instalaci.");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_FAILED_ASSETS, [](const Hyprutils::I18n::translationVarMap& vars) {
int assetsNo = std::stoi(vars.at("count"));
if (assetsNo <= 1)
return "Hyprlandu se nepodařilo načíst {count} nezbytnou součást. Za špatně odvedenou práci viňte tvůrce balíčku vaší distribuce!";
if (assetsNo <= 4)
return "Hyprlandu se nepodařilo načíst {count} nezbytné součásti. Za špatně odvedenou práci viňte tvůrce balíčku vaší distribuce!";
return "Hyprlandu se nepodařilo načíst {count} nezbytných součástí. Za špatně odvedenou práci viňte tvůrce balíčku vaší distribuce!";
});
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
"Rozložení vašich monitorů je nastaveno nesprávně. Monitor {name} se překrývá s ostatními monitory.\nVíce informací naleznete na wiki "
"(stránka Monitors). Toto <b>způsobí</b> problémy.");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_MONITOR_MODE_FAIL, "Monitoru {name} se nepodařilo nastavit žádný z požadovaných režimů, vrací se k režimu {mode}.");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_MONITOR_AUTO_SCALE, "Monitoru {name} bylo předáno neplatné měřítko: {scale}, použije se navrhované měřítko: {fixed_scale}");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN, "Nepodařilo se načíst plugin {name}: {error}");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_CM_RELOAD_FAILED, "Nepodařilo se znovu načíst CM shader, vrací se k rgba/rgbx.");
huEngine->registerEntry("cs_CZ", TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B, "Monitor {name}: široký barevný gamut je povolen, ale displej není v 10bitovém režimu.");
}
std::string I18n::CI18nEngine::localize(eI18nKeys key, const Hyprutils::I18n::translationVarMap& vars) {

View file

@ -7,6 +7,7 @@
#include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "xwayland/XWayland.hpp"
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) {
@ -300,9 +301,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
OPENINGON = getClosestNodeOnWorkspace(PNODE->workspaceID, MOUSECOORDS);
} else if (*PUSEACTIVE) {
if (g_pCompositor->m_lastWindow.lock() && !g_pCompositor->m_lastWindow->m_isFloating && g_pCompositor->m_lastWindow.lock() != pWindow &&
g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace && g_pCompositor->m_lastWindow->m_isMapped) {
OPENINGON = getNodeFromWindow(g_pCompositor->m_lastWindow.lock());
if (Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isFloating && Desktop::focusState()->window() != pWindow &&
Desktop::focusState()->window()->m_workspace == pWindow->m_workspace && Desktop::focusState()->window()->m_isMapped) {
OPENINGON = getNodeFromWindow(Desktop::focusState()->window());
} else {
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS));
}
@ -602,7 +603,7 @@ void CHyprDwindleLayout::onBeginDragWindow() {
void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorner corner, PHLWINDOW pWindow) {
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = pWindow ? pWindow : Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return;
@ -922,7 +923,7 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
if (silent) {
const auto PNODETOFOCUS = getClosestNodeOnWorkspace(originalWorkspaceID, originalPos);
if (PNODETOFOCUS && PNODETOFOCUS->pWindow.lock())
g_pCompositor->focusWindow(PNODETOFOCUS->pWindow.lock());
Desktop::focusState()->fullWindowFocus(PNODETOFOCUS->pWindow.lock());
}
}
@ -1139,20 +1140,20 @@ void CHyprDwindleLayout::onDisable() {
}
Vector2D CHyprDwindleLayout::predictSizeForNewWindowTiled() {
if (!g_pCompositor->m_lastMonitor)
if (!Desktop::focusState()->monitor())
return {};
// get window candidate
PHLWINDOW candidate = g_pCompositor->m_lastWindow.lock();
PHLWINDOW candidate = Desktop::focusState()->window();
if (!candidate)
candidate = g_pCompositor->m_lastMonitor->m_activeWorkspace->getFirstWindow();
candidate = Desktop::focusState()->monitor()->m_activeWorkspace->getFirstWindow();
// create a fake node
SDwindleNodeData node;
if (!candidate)
return g_pCompositor->m_lastMonitor->m_size;
return Desktop::focusState()->monitor()->m_size;
else {
const auto PNODE = getNodeFromWindow(candidate);

View file

@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp"
#include "../config/ConfigManager.hpp"
#include "../desktop/Window.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp"
@ -108,6 +109,9 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
xy = g_pXWaylandManager->xwaylandToWaylandCoords(xy);
desiredGeometry.x = xy.x;
desiredGeometry.y = xy.y;
} else if (pWindow->m_ruleApplicator->persistentSize().valueOrDefault()) {
desiredGeometry.w = pWindow->m_lastFloatingSize.x;
desiredGeometry.h = pWindow->m_lastFloatingSize.y;
}
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
@ -205,8 +209,8 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
static auto PAUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group");
const PHLWINDOW OPENINGON = g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace ?
g_pCompositor->m_lastWindow.lock() :
const PHLWINDOW OPENINGON = Desktop::focusState()->window() && Desktop::focusState()->window()->m_workspace == pWindow->m_workspace ?
Desktop::focusState()->window() :
(pWindow->m_workspace ? pWindow->m_workspace->getFirstWindow() : nullptr);
const bool FLOATEDINTOTILED = pWindow->m_isFloating && OPENINGON && !OPENINGON->m_isFloating;
const bool SWALLOWING = pWindow->m_swallowed || pWindow->m_groupSwallowed;
@ -301,7 +305,7 @@ void IHyprLayout::onBeginDragWindow() {
g_pKeybindManager->shadowKeybinds();
g_pCompositor->focusWindow(DRAGGINGWINDOW);
Desktop::focusState()->rawWindowFocus(DRAGGINGWINDOW);
g_pCompositor->changeWindowZOrder(DRAGGINGWINDOW, true);
}
@ -391,7 +395,7 @@ void IHyprLayout::onEndDragWindow() {
}
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
g_pCompositor->focusWindow(DRAGGINGWINDOW);
Desktop::focusState()->fullWindowFocus(DRAGGINGWINDOW);
g_pInputManager->m_wasDraggingWindow = false;
}
@ -782,7 +786,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
// fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(pWindow->m_monitor.lock());
if (pWindow == g_pCompositor->m_lastWindow)
if (pWindow == Desktop::focusState()->window())
m_lastTiledWindow = pWindow;
} else {
onWindowRemovedTiling(pWindow);
@ -849,7 +853,7 @@ void IHyprLayout::fitFloatingWindowOnMonitor(PHLWINDOW w, std::optional<CBox> tb
}
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = pWindow ? pWindow : Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return;
@ -924,7 +928,7 @@ PHLWINDOW IHyprLayout::getNextWindowCandidate(PHLWINDOW pWindow) {
pWindowCandidate = PWORKSPACE->getFirstWindow();
if (!pWindowCandidate || pWindow == pWindowCandidate || !pWindowCandidate->m_isMapped || pWindowCandidate->isHidden() || pWindowCandidate->m_X11ShouldntFocus ||
pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_monitor != g_pCompositor->m_lastMonitor)
pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_monitor != Desktop::focusState()->monitor())
return nullptr;
return pWindowCandidate;
@ -946,13 +950,13 @@ void IHyprLayout::bringWindowToTop(PHLWINDOW pWindow) {
void IHyprLayout::requestFocusForWindow(PHLWINDOW pWindow) {
bringWindowToTop(pWindow);
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->fullWindowFocus(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle());
}
Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // get all rules, see if we have any size overrides.
Vector2D sizeOverride = {};
if (g_pCompositor->m_lastMonitor) {
if (Desktop::focusState()->monitor()) {
// If `persistentsize` is set, use the stored size if available.
const bool HASPERSISTENTSIZE = pWindow->m_ruleApplicator->persistentSize().valueOrDefault();

View file

@ -9,6 +9,7 @@
#include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "xwayland/XWayland.hpp"
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) {
@ -93,7 +94,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
const auto PNODE = [&]() {
if (*PNEWONACTIVE != "none" && !BNEWISMASTER) {
const auto pLastNode = getNodeFromWindow(g_pCompositor->m_lastWindow.lock());
const auto pLastNode = getNodeFromWindow(Desktop::focusState()->window());
if (pLastNode && !(pLastNode->isMaster && (getMastersOnWorkspace(pWindow->workspaceID()) == 1 || *PNEWSTATUS == "slave"))) {
auto it = std::ranges::find(m_masterNodesData, *pLastNode);
if (!BNEWBEFOREACTIVE)
@ -111,8 +112,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact");
float lastSplitPercent = *PMFACT;
auto OPENINGON = isWindowTiled(g_pCompositor->m_lastWindow.lock()) && g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace ?
getNodeFromWindow(g_pCompositor->m_lastWindow.lock()) :
auto OPENINGON = isWindowTiled(Desktop::focusState()->window()) && Desktop::focusState()->window()->m_workspace == pWindow->m_workspace ?
getNodeFromWindow(Desktop::focusState()->window()) :
getMasterNodeOnWorkspace(pWindow->workspaceID());
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
@ -756,7 +757,7 @@ bool CHyprMasterLayout::isWindowTiled(PHLWINDOW pWindow) {
}
void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorner corner, PHLWINDOW pWindow) {
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = pWindow ? pWindow : Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return;
@ -985,14 +986,14 @@ void CHyprMasterLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
pWindow->m_monitor = PWINDOW2->m_monitor;
if (!silent) {
const auto pMonitor = pWindow->m_monitor.lock();
g_pCompositor->setActiveMonitor(pMonitor);
Desktop::focusState()->rawMonitorFocus(pMonitor);
}
onWindowCreatedTiling(pWindow);
} else {
// if same monitor, switch windows
switchWindows(pWindow, PWINDOW2);
if (silent)
g_pCompositor->focusWindow(PWINDOW2);
Desktop::focusState()->fullWindowFocus(PWINDOW2);
}
pWindow->updateGroupOutputs();
@ -1083,18 +1084,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!validMapped(PWINDOWTOCHANGETO))
return;
if (header.pWindow->isFullscreen()) {
const auto PWORKSPACE = header.pWindow->m_workspace;
const auto FSMODE = header.pWindow->m_fullscreenState.internal;
static auto INHERITFULLSCREEN = CConfigValue<Hyprlang::INT>("master:inherit_fullscreen");
g_pCompositor->setWindowFullscreenInternal(header.pWindow, FSMODE_NONE);
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
if (*INHERITFULLSCREEN)
g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, FSMODE);
} else {
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
}
Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO);
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
g_pInputManager->m_forcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
@ -1498,25 +1489,25 @@ void CHyprMasterLayout::replaceWindowDataWith(PHLWINDOW from, PHLWINDOW to) {
Vector2D CHyprMasterLayout::predictSizeForNewWindowTiled() {
static auto PNEWSTATUS = CConfigValue<std::string>("master:new_status");
if (!g_pCompositor->m_lastMonitor)
if (!Desktop::focusState()->monitor())
return {};
const int NODES = getNodesOnWorkspace(g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id);
const int NODES = getNodesOnWorkspace(Desktop::focusState()->monitor()->m_activeWorkspace->m_id);
if (NODES <= 0)
return g_pCompositor->m_lastMonitor->m_size;
return Desktop::focusState()->monitor()->m_size;
const auto MASTER = getMasterNodeOnWorkspace(g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id);
const auto MASTER = getMasterNodeOnWorkspace(Desktop::focusState()->monitor()->m_activeWorkspace->m_id);
if (!MASTER) // wtf
return {};
if (*PNEWSTATUS == "master") {
return MASTER->size;
} else {
const auto SLAVES = NODES - getMastersOnWorkspace(g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id);
const auto SLAVES = NODES - getMastersOnWorkspace(Desktop::focusState()->monitor()->m_activeWorkspace->m_id);
// TODO: make this better
return {g_pCompositor->m_lastMonitor->m_size.x - MASTER->size.x, g_pCompositor->m_lastMonitor->m_size.y / (SLAVES + 1)};
return {Desktop::focusState()->monitor()->m_size.x - MASTER->size.x, Desktop::focusState()->monitor()->m_size.y / (SLAVES + 1)};
}
return {};

View file

@ -1,5 +1,6 @@
#include "../config/ConfigValue.hpp"
#include "../devices/IKeyboard.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../managers/SeatManager.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/ShortcutsInhibit.hpp"
@ -53,7 +54,7 @@ static std::vector<std::pair<std::string, std::string>> getHyprlandLaunchEnv(PHL
if (!*PINITIALWSTRACKING || g_pConfigManager->m_isLaunchingExecOnce)
return {};
const auto PMONITOR = g_pCompositor->m_lastMonitor;
const auto PMONITOR = Desktop::focusState()->monitor();
if (!PMONITOR || !PMONITOR->m_activeWorkspace)
return {};
@ -336,15 +337,15 @@ static void updateRelativeCursorCoords() {
if (*PNOWARPS)
return;
if (g_pCompositor->m_lastWindow)
g_pCompositor->m_lastWindow->m_relativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_lastWindow->m_position;
if (Desktop::focusState()->window())
Desktop::focusState()->window()->m_relativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - Desktop::focusState()->window()->m_position;
}
bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
if (!monitor)
return false;
const auto LASTMONITOR = g_pCompositor->m_lastMonitor.lock();
const auto LASTMONITOR = Desktop::focusState()->monitor();
if (!LASTMONITOR)
return false;
if (LASTMONITOR == monitor) {
@ -355,7 +356,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
const auto PNEWMAINWORKSPACE = monitor->m_activeWorkspace;
g_pInputManager->unconstrainMouse();
@ -366,7 +367,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow();
if (PNEWWINDOW) {
updateRelativeCursorCoords();
g_pCompositor->focusWindow(PNEWWINDOW);
Desktop::focusState()->fullWindowFocus(PNEWWINDOW);
PNEWWINDOW->warpCursor();
if (*PNOWARPS == 0 || *PFOLLOWMOUSE < 2) {
@ -375,19 +376,19 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
g_pInputManager->m_forcedFocus.reset();
}
} else {
g_pCompositor->focusWindow(nullptr);
Desktop::focusState()->rawWindowFocus(nullptr);
g_pCompositor->warpCursorTo(monitor->middle());
}
g_pCompositor->setActiveMonitor(monitor);
Desktop::focusState()->rawMonitorFocus(monitor);
return true;
}
void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory) {
void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory, bool forceFSCycle) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO)
return;
@ -395,24 +396,11 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveF
// remove constraints
g_pInputManager->unconstrainMouse();
if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace && PLASTWINDOW->isFullscreen()) {
const auto PWORKSPACE = PLASTWINDOW->m_workspace;
const auto MODE = PWORKSPACE->m_fullscreenMode;
if (!PWINDOWTOCHANGETO->m_pinned)
g_pCompositor->setWindowFullscreenInternal(PLASTWINDOW, FSMODE_NONE);
g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory);
if (!PWINDOWTOCHANGETO->m_pinned)
g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE);
// warp the position + size animation, otherwise it looks weird.
PWINDOWTOCHANGETO->m_realPosition->warp();
PWINDOWTOCHANGETO->m_realSize->warp();
} else {
if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace && PLASTWINDOW->isFullscreen())
Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory, forceFSCycle);
else {
updateRelativeCursorCoords();
g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory);
Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory, forceFSCycle);
PWINDOWTOCHANGETO->warpCursor();
// Move mouse focus to the new window if required by current follow_mouse and warp modes
@ -426,7 +414,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveF
// event
const auto PNEWMON = PWINDOWTOCHANGETO->m_monitor.lock();
g_pCompositor->setActiveMonitor(PNEWMON);
Desktop::focusState()->rawMonitorFocus(PNEWMON);
}
}
};
@ -998,7 +986,7 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo
}
SDispatchResult CKeybindManager::killActive(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) {
Debug::log(ERR, "killActive: no window found");
@ -1011,10 +999,10 @@ SDispatchResult CKeybindManager::killActive(std::string args) {
}
SDispatchResult CKeybindManager::closeActive(std::string args) {
if (g_pCompositor->m_lastWindow && g_pCompositor->m_lastWindow->m_closeableSince > Time::steadyNow())
if (Desktop::focusState()->window() && Desktop::focusState()->window()->m_closeableSince > Time::steadyNow())
return {.success = false, .error = "can't close window, it's not closeable yet (noclosefor)"};
g_pCompositor->closeWindow(g_pCompositor->m_lastWindow.lock());
g_pCompositor->closeWindow(Desktop::focusState()->window());
return {};
}
@ -1058,13 +1046,13 @@ SDispatchResult CKeybindManager::signalActive(std::string args) {
Debug::log(ERR, "signalActive: invalid signal number {}", SIGNALNUM);
return {.success = false, .error = std::format("signalActive: invalid signal number {}", SIGNALNUM)};
}
kill(g_pCompositor->m_lastWindow.lock()->getPID(), SIGNALNUM);
kill(Desktop::focusState()->window()->getPID(), SIGNALNUM);
} catch (const std::exception& e) {
Debug::log(ERR, "signalActive: invalid signal format \"{}\"", args);
return {.success = false, .error = std::format("signalActive: invalid signal format \"{}\"", args)};
}
kill(g_pCompositor->m_lastWindow.lock()->getPID(), std::stoi(args));
kill(Desktop::focusState()->window()->getPID(), std::stoi(args));
return {};
}
@ -1108,7 +1096,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@ -1118,7 +1106,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
// remove drag status
if (!g_pInputManager->m_currentlyDraggedWindow.expired())
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
CKeybindManager::changeMouseBindMode(MBIND_INVALID);
if (PWINDOW->m_groupData.pNextWindow.lock() && PWINDOW->m_groupData.pNextWindow.lock() != PWINDOW) {
const auto PCURRENT = PWINDOW->getGroupCurrent();
@ -1161,7 +1149,7 @@ SDispatchResult CKeybindManager::setActiveTiled(std::string args) {
}
SDispatchResult CKeybindManager::centerWindow(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW || !PWINDOW->m_isFloating || PWINDOW->isFullscreen())
return {.success = false, .error = "No floating window found"};
@ -1184,7 +1172,7 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) {
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@ -1225,7 +1213,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
static auto PWORKSPACECENTERON = CConfigValue<Hyprlang::INT>("binds:workspace_center_on");
static auto PHIDESPECIALONWORKSPACECHANGE = CConfigValue<Hyprlang::INT>("binds:hide_special_on_workspace_change");
const auto PMONITOR = g_pCompositor->m_lastMonitor.lock();
const auto PMONITOR = Desktop::focusState()->monitor();
if (!PMONITOR)
return {.success = false, .error = "Last monitor not found"};
@ -1275,7 +1263,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
updateRelativeCursorCoords();
g_pCompositor->setActiveMonitor(PMONITORWORKSPACEOWNER);
Desktop::focusState()->rawMonitorFocus(PMONITORWORKSPACEOWNER);
if (BISWORKSPACECURRENT) {
if (*PALLOWWORKSPACECYCLES)
@ -1292,7 +1280,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
if (PMONITOR != PMONITORWORKSPACEOWNER) {
Vector2D middle = PMONITORWORKSPACEOWNER->middle();
if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) {
g_pCompositor->focusWindow(PLAST);
Desktop::focusState()->fullWindowFocus(PLAST);
if (*PWORKSPACECENTERON == 1)
middle = PLAST->middle();
}
@ -1300,7 +1288,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
}
if (!g_pInputManager->m_lastFocusOnLS) {
if (g_pCompositor->m_lastFocus)
if (Desktop::focusState()->surface())
g_pInputManager->sendMotionEventsToFocused();
else
g_pInputManager->simulateMouseMovement();
@ -1320,7 +1308,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
}
SDispatchResult CKeybindManager::fullscreenActive(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
const auto ARGS = CConstVarList(args, 2, ' ');
if (!PWINDOW)
@ -1344,7 +1332,7 @@ SDispatchResult CKeybindManager::fullscreenActive(std::string args) {
}
SDispatchResult CKeybindManager::fullscreenStateActive(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
const auto ARGS = CVarList(args, 3, ' ');
if (!PWINDOW)
@ -1390,7 +1378,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
args = args.substr(0, args.find_last_of(','));
} else {
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
}
if (!PWINDOW)
@ -1420,7 +1408,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
const auto FULLSCREENMODE = PWINDOW->m_fullscreenState.internal;
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
pMonitor = pWorkspace->m_monitor.lock();
g_pCompositor->setActiveMonitor(pMonitor);
Desktop::focusState()->rawMonitorFocus(pMonitor);
g_pCompositor->setWindowFullscreenInternal(PWINDOW, FULLSCREENMODE);
} else {
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
@ -1440,7 +1428,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
pMonitor->changeWorkspace(pWorkspace);
g_pCompositor->focusWindow(PWINDOW);
Desktop::focusState()->fullWindowFocus(PWINDOW);
PWINDOW->warpCursor();
return {};
@ -1453,7 +1441,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
args = args.substr(0, args.find_last_of(','));
} else {
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
}
if (!PWINDOW)
@ -1480,9 +1468,9 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
}
if (PWINDOW == g_pCompositor->m_lastWindow) {
if (PWINDOW == Desktop::focusState()->window()) {
if (const auto PATCOORDS = g_pCompositor->vectorToWindowUnified(OLDMIDDLE, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING, PWINDOW); PATCOORDS)
g_pCompositor->focusWindow(PATCOORDS);
Desktop::focusState()->fullWindowFocus(PATCOORDS);
else
g_pInputManager->refocus();
}
@ -1501,7 +1489,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
return {.success = false, .error = std::format("Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW) {
if (*PMONITORFALLBACK)
tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg));
@ -1529,7 +1517,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
// Found window in direction, switch to it
if (PWINDOWTOCHANGETO) {
switchToWindow(PWINDOWTOCHANGETO);
switchToWindow(PWINDOWTOCHANGETO, false, *PFULLCYCLE && PLASTWINDOW->isFullscreen());
return {};
}
@ -1587,8 +1575,8 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) {
const auto PWINDOWURGENT = g_pCompositor->getUrgentWindow();
const auto PWINDOWPREV = g_pCompositor->m_lastWindow.lock() ? (g_pCompositor->m_windowFocusHistory.size() < 2 ? nullptr : g_pCompositor->m_windowFocusHistory[1].lock()) :
(g_pCompositor->m_windowFocusHistory.empty() ? nullptr : g_pCompositor->m_windowFocusHistory[0].lock());
const auto PWINDOWPREV = Desktop::focusState()->window() ? (Desktop::focusState()->windowHistory().size() < 2 ? nullptr : Desktop::focusState()->windowHistory()[1].lock()) :
(Desktop::focusState()->windowHistory().empty() ? nullptr : Desktop::focusState()->windowHistory()[0].lock());
if (!PWINDOWURGENT && !PWINDOWPREV)
return {.success = false, .error = "Window not found"};
@ -1599,8 +1587,8 @@ SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) {
}
SDispatchResult CKeybindManager::focusCurrentOrLast(std::string args) {
const auto PWINDOWPREV = g_pCompositor->m_lastWindow.lock() ? (g_pCompositor->m_windowFocusHistory.size() < 2 ? nullptr : g_pCompositor->m_windowFocusHistory[1].lock()) :
(g_pCompositor->m_windowFocusHistory.empty() ? nullptr : g_pCompositor->m_windowFocusHistory[0].lock());
const auto PWINDOWPREV = Desktop::focusState()->window() ? (Desktop::focusState()->windowHistory().size() < 2 ? nullptr : Desktop::focusState()->windowHistory()[1].lock()) :
(Desktop::focusState()->windowHistory().empty() ? nullptr : Desktop::focusState()->windowHistory()[0].lock());
if (!PWINDOWPREV)
return {.success = false, .error = "Window not found"};
@ -1612,7 +1600,7 @@ SDispatchResult CKeybindManager::focusCurrentOrLast(std::string args) {
SDispatchResult CKeybindManager::swapActive(std::string args) {
char arg = args[0];
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
PHLWINDOW PWINDOWTOCHANGETO = nullptr;
if (!PLASTWINDOW)
@ -1663,7 +1651,7 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) {
return {.success = false, .error = std::format("Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "Window to move not found"};
@ -1729,7 +1717,7 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) {
}
SDispatchResult CKeybindManager::toggleGroup(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@ -1746,7 +1734,7 @@ SDispatchResult CKeybindManager::toggleGroup(std::string args) {
}
SDispatchResult CKeybindManager::changeGroupActive(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@ -1779,7 +1767,7 @@ SDispatchResult CKeybindManager::changeGroupActive(std::string args) {
SDispatchResult CKeybindManager::toggleSplit(std::string args) {
SLayoutMessageHeader header;
header.pWindow = g_pCompositor->m_lastWindow.lock();
header.pWindow = Desktop::focusState()->window();
if (!header.pWindow)
return {.success = false, .error = "Window not found"};
@ -1796,7 +1784,7 @@ SDispatchResult CKeybindManager::toggleSplit(std::string args) {
SDispatchResult CKeybindManager::swapSplit(std::string args) {
SLayoutMessageHeader header;
header.pWindow = g_pCompositor->m_lastWindow.lock();
header.pWindow = Desktop::focusState()->window();
if (!header.pWindow)
return {.success = false, .error = "Window not found"};
@ -1826,7 +1814,7 @@ SDispatchResult CKeybindManager::alterSplitRatio(std::string args) {
return {.success = false, .error = "Splitratio invalid in alterSplitRatio!"};
}
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "Window not found"};
@ -1856,7 +1844,7 @@ SDispatchResult CKeybindManager::moveCursorToCorner(std::string arg) {
return {.success = false, .error = "moveCursorToCorner, corner not 0 - 3."};
}
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@ -1918,7 +1906,7 @@ SDispatchResult CKeybindManager::moveCursor(std::string args) {
SDispatchResult CKeybindManager::workspaceOpt(std::string args) {
// current workspace
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!PWORKSPACE)
return {.success = false, .error = "Workspace not found"}; // ????
@ -1965,7 +1953,7 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) {
}
// recalc mon
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_lastMonitor->m_id);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(Desktop::focusState()->monitor()->m_id);
return {};
}
@ -2011,7 +1999,7 @@ SDispatchResult CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args)
}
// get the current workspace
const auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
const auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!PCURRENTWORKSPACE) {
Debug::log(ERR, "moveCurrentWorkspaceToMonitor invalid workspace!");
return {.success = false, .error = "moveCurrentWorkspaceToMonitor invalid workspace!"};
@ -2062,7 +2050,7 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
return {.success = false, .error = "focusWorkspaceOnCurrentMonitor invalid workspace!"};
}
const auto PCURRMONITOR = g_pCompositor->m_lastMonitor.lock();
const auto PCURRMONITOR = Desktop::focusState()->monitor();
if (!PCURRMONITOR) {
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!");
@ -2117,7 +2105,7 @@ SDispatchResult CKeybindManager::toggleSpecialWorkspace(std::string args) {
}
bool requestedWorkspaceIsAlreadyOpen = false;
const auto PMONITOR = g_pCompositor->m_lastMonitor;
const auto PMONITOR = Desktop::focusState()->monitor();
auto specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID();
for (auto const& m : g_pCompositor->m_monitors) {
@ -2183,7 +2171,7 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) {
}
SDispatchResult CKeybindManager::resizeActive(std::string args) {
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window found"};
@ -2205,7 +2193,7 @@ SDispatchResult CKeybindManager::resizeActive(std::string args) {
}
SDispatchResult CKeybindManager::moveActive(std::string args) {
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window found"};
@ -2271,9 +2259,9 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) {
}
SDispatchResult CKeybindManager::circleNext(std::string arg) {
if (g_pCompositor->m_lastWindow.expired()) {
if (!Desktop::focusState()->window()) {
// if we have a clear focus, find the first window and get the next focusable.
const auto PWS = g_pCompositor->m_lastMonitor->m_activeWorkspace;
const auto PWS = Desktop::focusState()->monitor()->m_activeWorkspace;
if (PWS && PWS->getWindows() > 0) {
const auto PWINDOW = PWS->getFirstWindow();
switchToWindow(PWINDOW);
@ -2294,8 +2282,8 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) {
const auto PREV = args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l");
const auto NEXT = args.contains("next") || args.contains("n"); // prev is default in classic alt+tab
const auto HIST = args.contains("hist") || args.contains("h");
const auto& w = HIST ? g_pCompositor->getWindowCycleHist(g_pCompositor->m_lastWindow, true, floatStatus, VISIBLE, NEXT) :
g_pCompositor->getWindowCycle(g_pCompositor->m_lastWindow.lock(), true, floatStatus, VISIBLE, PREV);
const auto& w = HIST ? g_pCompositor->getWindowCycleHist(Desktop::focusState()->window(), true, floatStatus, VISIBLE, NEXT) :
g_pCompositor->getWindowCycle(Desktop::focusState()->window(), true, floatStatus, VISIBLE, PREV);
switchToWindow(w, HIST);
@ -2318,40 +2306,13 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) {
updateRelativeCursorCoords();
if (g_pCompositor->m_lastMonitor && g_pCompositor->m_lastMonitor->m_activeWorkspace != PWINDOW->m_workspace &&
g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace != PWINDOW->m_workspace) {
if (Desktop::focusState()->monitor() && Desktop::focusState()->monitor()->m_activeWorkspace != PWINDOW->m_workspace &&
Desktop::focusState()->monitor()->m_activeSpecialWorkspace != PWINDOW->m_workspace) {
Debug::log(LOG, "Fake executing workspace to move focus");
changeworkspace(PWORKSPACE->getConfigName());
}
if (PWORKSPACE->m_hasFullscreenWindow) {
const auto FSWINDOW = PWORKSPACE->getFullscreenWindow();
const auto FSMODE = PWORKSPACE->m_fullscreenMode;
if (PWINDOW->m_isFloating) {
// don't make floating implicitly fs
if (!PWINDOW->m_createdOverFullscreen) {
g_pCompositor->changeWindowZOrder(PWINDOW, true);
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
PWORKSPACE, PWORKSPACE->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
}
g_pCompositor->focusWindow(PWINDOW);
} else {
if (FSWINDOW != PWINDOW && !PWINDOW->m_pinned)
g_pCompositor->setWindowFullscreenClient(FSWINDOW, FSMODE_NONE);
g_pCompositor->focusWindow(PWINDOW);
if (FSWINDOW != PWINDOW && !PWINDOW->m_pinned)
g_pCompositor->setWindowFullscreenClient(PWINDOW, FSMODE);
// warp the position + size animation, otherwise it looks weird.
PWINDOW->m_realPosition->warp();
PWINDOW->m_realSize->warp();
}
} else
g_pCompositor->focusWindow(PWINDOW);
Desktop::focusState()->fullWindowFocus(PWINDOW, nullptr, false);
PWINDOW->warpCursor();
@ -2363,7 +2324,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) {
CVarList vars{args, 0, 's', true};
if (vars.size() == 1)
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
else if (vars.size() == 2)
PWINDOW = g_pCompositor->getWindowByRegex(vars[1]);
else
@ -2378,7 +2339,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) {
}
SDispatchResult CKeybindManager::toggleSwallow(std::string args) {
PHLWINDOWREF pWindow = g_pCompositor->m_lastWindow;
PHLWINDOWREF pWindow = Desktop::focusState()->window();
if (!valid(pWindow) || !valid(pWindow->m_swallowed))
return {};
@ -2436,7 +2397,7 @@ SDispatchResult CKeybindManager::pass(std::string regexp) {
return {.success = false, .error = "No kb in pass?"};
}
const auto XWTOXW = PWINDOW->m_isX11 && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isX11;
const auto XWTOXW = PWINDOW->m_isX11 && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isX11;
const auto LASTMOUSESURF = g_pSeatManager->m_state.pointerFocus.lock();
const auto LASTKBSURF = g_pSeatManager->m_state.keyboardFocus.lock();
@ -2573,7 +2534,7 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
const std::string regexp = ARGS[2];
PHLWINDOW PWINDOW = nullptr;
const auto LASTSURFACE = g_pCompositor->m_lastFocus.lock();
const auto LASTSURFACE = Desktop::focusState()->surface();
//if regexp is not empty, send shortcut to current window
//else, don't change focus
@ -2598,10 +2559,10 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
//copied the rest from pass and modified it
// if wl -> xwl, activate destination
if (PWINDOW && PWINDOW->m_isX11 && g_pCompositor->m_lastWindow && !g_pCompositor->m_lastWindow->m_isX11)
if (PWINDOW && PWINDOW->m_isX11 && Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isX11)
g_pXWaylandManager->activateSurface(PWINDOW->m_wlSurface->resource(), true);
// if xwl -> xwl, send to current. Timing issues make this not work.
if (PWINDOW && PWINDOW->m_isX11 && g_pCompositor->m_lastWindow && g_pCompositor->m_lastWindow->m_isX11)
if (PWINDOW && PWINDOW->m_isX11 && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isX11)
PWINDOW = nullptr;
g_pSeatManager->sendKeyboardMods(MOD, 0, 0, 0);
@ -2653,7 +2614,7 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
}
SDispatchResult CKeybindManager::layoutmsg(std::string msg) {
SLayoutMessageHeader hd = {g_pCompositor->m_lastWindow.lock()};
SLayoutMessageHeader hd = {Desktop::focusState()->window()};
g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg);
return {};
@ -2690,14 +2651,14 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) {
PHLWINDOW toSwap = nullptr;
if (g_pCompositor->m_lastWindow.expired())
if (!Desktop::focusState()->window())
return {};
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
const auto PLASTCYCLED =
validMapped(g_pCompositor->m_lastWindow->m_lastCycledWindow) && g_pCompositor->m_lastWindow->m_lastCycledWindow->m_workspace == PLASTWINDOW->m_workspace ?
g_pCompositor->m_lastWindow->m_lastCycledWindow.lock() :
validMapped(Desktop::focusState()->window()->m_lastCycledWindow) && Desktop::focusState()->window()->m_lastCycledWindow->m_workspace == PLASTWINDOW->m_workspace ?
Desktop::focusState()->window()->m_lastCycledWindow.lock() :
nullptr;
const bool NEED_PREV = arg == "last" || arg == "l" || arg == "prev" || arg == "p";
@ -2711,7 +2672,7 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) {
PLASTWINDOW->m_lastCycledWindow = toSwap;
g_pCompositor->focusWindow(PLASTWINDOW);
Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
return {};
}
@ -2741,7 +2702,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) {
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) {
Debug::log(ERR, "pin: window not found");
@ -2827,8 +2788,8 @@ SDispatchResult CKeybindManager::changeMouseBindMode(const eMouseBindMode MODE)
}
SDispatchResult CKeybindManager::bringActiveToTop(std::string args) {
if (g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isFloating)
g_pCompositor->changeWindowZOrder(g_pCompositor->m_lastWindow.lock(), true);
if (Desktop::focusState()->window() && Desktop::focusState()->window()->m_isFloating)
g_pCompositor->changeWindowZOrder(Desktop::focusState()->window(), true);
return {};
}
@ -2838,8 +2799,8 @@ SDispatchResult CKeybindManager::alterZOrder(std::string args) {
const auto POSITION = args.substr(0, args.find_first_of(','));
auto PWINDOW = g_pCompositor->getWindowByRegex(WINDOWREGEX);
if (!PWINDOW && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isFloating)
PWINDOW = g_pCompositor->m_lastWindow.lock();
if (!PWINDOW && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isFloating)
PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) {
Debug::log(ERR, "alterZOrder: no window");
@ -2875,7 +2836,7 @@ SDispatchResult CKeybindManager::lockGroups(std::string args) {
}
SDispatchResult CKeybindManager::lockActiveGroup(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "No window found"};
@ -2916,7 +2877,7 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
pWindowInDirection->setGroupCurrent(pWindow);
pWindow->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->fullWindowFocus(pWindow);
pWindow->warpCursor();
g_pEventManager->postEvent(SHyprIPCEvent{"moveintogroup", std::format("{:x}", rc<uintptr_t>(pWindow.get()))});
@ -2953,10 +2914,10 @@ void CKeybindManager::moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string&
}
if (*BFOCUSREMOVEDWINDOW) {
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->fullWindowFocus(pWindow);
pWindow->warpCursor();
} else {
g_pCompositor->focusWindow(PWINDOWPREV);
Desktop::focusState()->fullWindowFocus(PWINDOWPREV);
PWINDOWPREV->warpCursor();
}
@ -2976,7 +2937,7 @@ SDispatchResult CKeybindManager::moveIntoGroup(std::string args) {
return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW || PWINDOW->m_groupData.deny)
return {};
@ -3006,7 +2967,7 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) {
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
PWINDOW = g_pCompositor->m_lastWindow.lock();
PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "No window found"};
@ -3029,7 +2990,7 @@ SDispatchResult CKeybindManager::moveWindowOrGroup(std::string args) {
return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "No window found"};
@ -3088,7 +3049,7 @@ SDispatchResult CKeybindManager::setIgnoreGroupLock(std::string args) {
}
SDispatchResult CKeybindManager::denyWindowFromGroup(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW || (PWINDOW && PWINDOW->m_groupData.pNextWindow.lock()))
return {};
@ -3120,7 +3081,7 @@ SDispatchResult CKeybindManager::global(std::string args) {
SDispatchResult CKeybindManager::moveGroupWindow(std::string args) {
const auto BACK = args == "b" || args == "prev";
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window found"};
@ -3186,7 +3147,7 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
if (vars.size() < 3)
return {.success = false, .error = "Not enough args"};
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
const auto PLASTWINDOW = Desktop::focusState()->window();
const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[0]);
if (!PWINDOW)
@ -3321,10 +3282,11 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
if (!(PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() == noFocus)) {
g_pCompositor->focusWindow(nullptr);
g_pCompositor->focusWindow(PWINDOW);
g_pCompositor->focusWindow(PLASTWINDOW);
if (PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() != noFocus) {
// FIXME: what the fuck is going on here? -vax
Desktop::focusState()->rawWindowFocus(nullptr);
Desktop::focusState()->fullWindowFocus(PWINDOW);
Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
}
if (PROP == "no_vrr")

View file

@ -163,7 +163,8 @@ class CKeybindManager {
static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false);
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false, bool forceFSCycle = false);
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace, const std::string& execRuleToken = "");
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);

View file

@ -14,6 +14,7 @@
#include "../managers/HookSystemManager.hpp"
#include "../render/Renderer.hpp"
#include "../render/OpenGL.hpp"
#include "../desktop/state/FocusState.hpp"
#include "SeatManager.hpp"
#include "../helpers/time/Time.hpp"
#include <cstring>
@ -799,7 +800,7 @@ void CPointerManager::warpAbsolute(Vector2D abs, SP<IHID> dev) {
auto outputMappedArea = [&mappedArea](const std::string& output) {
if (output == "current") {
if (const auto PLASTMONITOR = g_pCompositor->m_lastMonitor.lock(); PLASTMONITOR)
if (const auto PLASTMONITOR = Desktop::focusState()->monitor(); PLASTMONITOR)
return PLASTMONITOR->logicalBox();
} else if (const auto PMONITOR = g_pCompositor->getMonitorFromString(output); PMONITOR)
return PMONITOR->logicalBox();
@ -927,7 +928,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
listener->frame = pointer->m_pointerEvents.frame.listen([] {
bool shouldSkip = false;
if (!g_pSeatManager->m_mouse.expired() && g_pInputManager->isLocked()) {
auto PMONITOR = g_pCompositor->m_lastMonitor.get();
auto PMONITOR = Desktop::focusState()->monitor().get();
shouldSkip = PMONITOR && PMONITOR->shouldSkipScheduleFrameOnMouseEvent();
}
g_pSeatManager->m_isPointerFrameSkipped = shouldSkip;

View file

@ -150,7 +150,7 @@ CProtocolManager::CProtocolManager() {
PROTO::tearing = makeUnique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
PROTO::fractional = makeUnique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
PROTO::xdgOutput = makeUnique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
PROTO::cursorShape = makeUnique<CCursorShapeProtocol>(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
PROTO::cursorShape = makeUnique<CCursorShapeProtocol>(&wp_cursor_shape_manager_v1_interface, 2, "CursorShape");
PROTO::idleInhibit = makeUnique<CIdleInhibitProtocol>(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit");
PROTO::relativePointer = makeUnique<CRelativePointerProtocol>(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer");
PROTO::xdgDecoration = makeUnique<CXDGDecorationProtocol>(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration");

View file

@ -6,6 +6,7 @@
#include "../protocols/PrimarySelection.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../devices/IKeyboard.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../managers/input/InputManager.hpp"
@ -659,7 +660,7 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
// If this was a popup grab, focus its parent window to maintain context
if (validMapped(parentWindow)) {
g_pCompositor->focusWindow(parentWindow);
Desktop::focusState()->rawWindowFocus(parentWindow);
Debug::log(LOG, "[seatmgr] Refocused popup parent window {} (follow_mouse={})", parentWindow->m_title, *PFOLLOWMOUSE);
} else
g_pInputManager->refocusLastWindow(PMONITOR);
@ -689,10 +690,10 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
refocus = layer->m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
if (refocus) {
auto candidate = g_pCompositor->m_lastWindow.lock();
auto candidate = Desktop::focusState()->window();
if (candidate)
g_pCompositor->focusWindow(candidate);
Desktop::focusState()->rawWindowFocus(candidate);
}
if (oldGrab->m_onEnd)

View file

@ -4,6 +4,7 @@
#include "../protocols/FractionalScale.hpp"
#include "../protocols/SessionLock.hpp"
#include "../render/Renderer.hpp"
#include "../desktop/state/FocusState.hpp"
#include "./managers/SeatManager.hpp"
#include "./managers/input/InputManager.hpp"
#include "./managers/eventLoop/EventLoopManager.hpp"
@ -25,8 +26,8 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
});
listeners.destroy = surface_->m_events.destroy.listen([this] {
if (pWlrSurface == g_pCompositor->m_lastFocus)
g_pCompositor->m_lastFocus.reset();
if (pWlrSurface == Desktop::focusState()->surface())
Desktop::focusState()->surface().reset();
g_pSessionLockManager->removeSessionLockSurface(this);
});
@ -34,7 +35,7 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
listeners.commit = surface_->m_events.commit.listen([this] {
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
if (mapped && !g_pCompositor->m_lastFocus)
if (mapped && !Desktop::focusState()->surface())
g_pInputManager->simulateMouseMovement();
if (PMONITOR)
@ -82,13 +83,13 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
m_sessionLock->listeners.destroy = pLock->m_events.destroyed.listen([this] {
m_sessionLock.reset();
g_pCompositor->focusSurface(nullptr);
Desktop::focusState()->rawSurfaceFocus(nullptr);
for (auto const& m : g_pCompositor->m_monitors)
g_pHyprRenderer->damageMonitor(m);
});
g_pCompositor->focusSurface(nullptr);
Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pSeatManager->setGrab(nullptr);
const bool NOACTIVEMONS = std::ranges::all_of(g_pCompositor->m_monitors, [](const auto& m) { return !m->m_enabled || !m->m_dpmsStatus; });
@ -196,14 +197,14 @@ void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
std::erase_if(m_sessionLock->vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
if (g_pCompositor->m_lastFocus)
if (Desktop::focusState()->surface())
return;
for (auto const& sls : m_sessionLock->vSessionLockSurfaces) {
if (!sls->mapped)
continue;
g_pCompositor->focusSurface(sls->surface->surface());
Desktop::focusState()->rawSurfaceFocus(sls->surface->surface());
break;
}
}

View file

@ -396,6 +396,10 @@ std::string CXCursorManager::getLegacyShapeName(std::string const& shape) {
return "left_ptr";
else if (shape == "zoom-out")
return "left_ptr";
else if (shape == "dnd-ask")
return "dnd-copy";
else if (shape == "all-resize")
return "fleur";
return std::string();
};

View file

@ -1,5 +1,6 @@
#include "XWaylandManager.hpp"
#include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../events/Events.hpp"
#include "../config/ConfigValue.hpp"
#include "../helpers/Monitor.hpp"
@ -69,8 +70,8 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {
pWindow->m_xdgSurface->m_toplevel->setActive(activate);
if (activate) {
g_pCompositor->m_lastFocus = getWindowSurface(pWindow);
g_pCompositor->m_lastWindow = pWindow;
Desktop::focusState()->surface() = getWindowSurface(pWindow);
Desktop::focusState()->window() = pWindow;
}
if (!pWindow->m_pinned)

View file

@ -18,16 +18,7 @@
static int wlTick(SP<CEventLoopTimer> self, void* data) {
if (g_pAnimationManager)
g_pAnimationManager->onTicked();
if (g_pCompositor->m_sessionActive && g_pAnimationManager && g_pHookSystem && !g_pCompositor->m_unsafeState &&
std::ranges::any_of(g_pCompositor->m_monitors, [](const auto& mon) { return mon->m_enabled && mon->m_output; })) {
g_pAnimationManager->tick();
EMIT_HOOK_EVENT("tick", nullptr);
}
if (g_pAnimationManager && g_pAnimationManager->shouldTickForNext())
g_pAnimationManager->scheduleTick();
g_pAnimationManager->frameTick();
return 0;
}
@ -249,26 +240,40 @@ void CHyprAnimationManager::tick() {
tickDone();
}
void CHyprAnimationManager::frameTick() {
onTicked();
if (!shouldTickForNext())
return;
if (!g_pCompositor->m_sessionActive || !g_pHookSystem || g_pCompositor->m_unsafeState ||
!std::ranges::any_of(g_pCompositor->m_monitors, [](const auto& mon) { return mon->m_enabled && mon->m_output; }))
return;
if (!m_lastTickValid || m_lastTickTimer.getMillis() >= 1.0f) {
m_lastTickTimer.reset();
m_lastTickValid = true;
tick();
EMIT_HOOK_EVENT("tick", nullptr);
}
if (shouldTickForNext())
scheduleTick();
}
void CHyprAnimationManager::scheduleTick() {
if (m_tickScheduled)
return;
m_tickScheduled = true;
const auto PMOSTHZ = g_pHyprRenderer->m_mostHzMonitor;
if (!PMOSTHZ) {
m_animationTimer->updateTimeout(std::chrono::milliseconds(16));
if (!m_animationTimer || !g_pEventLoopManager) {
m_tickScheduled = false;
return;
}
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->m_refreshRate);
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(Time::steadyNow() - PMOSTHZ->m_lastPresentationTimer.chrono()).count() / 1000.F;
const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it
m_animationTimer->updateTimeout(std::chrono::milliseconds(sc<int>(std::floor(TOPRES))));
m_animationTimer->updateTimeout(std::chrono::milliseconds(1));
}
void CHyprAnimationManager::onTicked() {

View file

@ -6,6 +6,7 @@
#include "../../defines.hpp"
#include "../../helpers/AnimatedVariable.hpp"
#include "../../desktop/DesktopTypes.hpp"
#include "../../helpers/time/Timer.hpp"
#include "../eventLoop/EventLoopTimer.hpp"
class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
@ -13,6 +14,7 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
CHyprAnimationManager();
void tick();
void frameTick();
virtual void scheduleTick();
virtual void onTicked();
@ -52,7 +54,9 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
float m_lastTickTimeMs;
private:
bool m_tickScheduled = false;
bool m_tickScheduled = false;
bool m_lastTickValid = false;
CTimer m_lastTickTimer;
};
inline UP<CHyprAnimationManager> g_pAnimationManager;

View file

@ -9,6 +9,7 @@
#include "../../config/ConfigManager.hpp"
#include "../../desktop/Window.hpp"
#include "../../desktop/LayerSurface.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/CursorShape.hpp"
#include "../../protocols/IdleInhibit.hpp"
#include "../../protocols/RelativePointer.hpp"
@ -168,18 +169,18 @@ void CInputManager::simulateMouseMovement() {
}
void CInputManager::sendMotionEventsToFocused() {
if (!g_pCompositor->m_lastFocus || isConstrained())
if (!Desktop::focusState()->surface() || isConstrained())
return;
// todo: this sucks ass
const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_lastFocus.lock());
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock());
const auto PWINDOW = g_pCompositor->getWindowFromSurface(Desktop::focusState()->surface());
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_realPosition->goal() : (PLS ? Vector2D{PLS->m_geometry.x, PLS->m_geometry.y} : Vector2D{}));
m_emptyFocusCursorSet = false;
g_pSeatManager->setPointerFocus(g_pCompositor->m_lastFocus.lock(), LOCAL);
g_pSeatManager->setPointerFocus(Desktop::focusState()->surface(), LOCAL);
}
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, std::optional<Vector2D> overridePos) {
@ -223,7 +224,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
m_lastCursorPosFloored = MOUSECOORDSFLOORED;
const auto PMONITOR = isLocked() && g_pCompositor->m_lastMonitor ? g_pCompositor->m_lastMonitor.lock() : g_pCompositor->getMonitorFromCursor();
const auto PMONITOR = isLocked() && Desktop::focusState()->monitor() ? Desktop::focusState()->monitor() : g_pCompositor->getMonitorFromCursor();
// this can happen if there are no displays hooked up to Hyprland
if (PMONITOR == nullptr)
@ -239,7 +240,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
// constraints
if (!g_pSeatManager->m_mouse.expired() && isConstrained()) {
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_lastFocus.lock());
const auto SURF = CWLSurface::fromResource(Desktop::focusState()->surface());
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
if (CONSTRAINT) {
@ -263,8 +264,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
Debug::log(ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", rc<uintptr_t>(SURF.get()), rc<uintptr_t>(CONSTRAINT.get()));
}
if (PMONITOR != g_pCompositor->m_lastMonitor && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
g_pCompositor->setActiveMonitor(PMONITOR);
if (PMONITOR != Desktop::focusState()->monitor() && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
Desktop::focusState()->rawMonitorFocus(PMONITOR);
// check for windows that have focus priority like our permission popups
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, FOCUS_PRIORITY);
@ -277,7 +278,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
const auto foundLockSurface = PSESSIONLOCKSURFACE ? PSESSIONLOCKSURFACE->surface->surface() : nullptr;
g_pCompositor->focusSurface(foundLockSurface);
Desktop::focusState()->rawSurfaceFocus(foundLockSurface);
// search for interactable abovelock surfaces for pointer focus, or use session lock surface if not found
for (auto& lsl : PMONITOR->m_layerSurfaceLayers | std::views::reverse) {
@ -317,7 +318,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
// if we are holding a pointer button,
// and we're not dnd-ing, don't refocus. Keep focus on last surface.
if (!PROTO::data->dndActive() && !m_currentlyHeldButtons.empty() && g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus->m_mapped &&
if (!PROTO::data->dndActive() && !m_currentlyHeldButtons.empty() && Desktop::focusState()->surface() && Desktop::focusState()->surface()->m_mapped &&
g_pSeatManager->m_state.pointerFocus && !m_hardInput) {
foundSurface = g_pSeatManager->m_state.pointerFocus.lock();
@ -339,7 +340,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
surfacePos = BOX->pos();
pFoundLayerSurface = HLSurface->getLayer();
if (!pFoundLayerSurface)
pFoundWindow = !PWINDOW || PWINDOW->isHidden() ? g_pCompositor->m_lastWindow.lock() : PWINDOW;
pFoundWindow = !PWINDOW || PWINDOW->isHidden() ? Desktop::focusState()->window() : PWINDOW;
} else // reset foundSurface, find one normally
foundSurface = nullptr;
} else // reset foundSurface, find one normally
@ -461,7 +462,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface);
if (g_pPointerManager->softwareLockedFor(PMONITOR->m_self.lock()) > 0 && !skipFrameSchedule)
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_lastMonitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
g_pCompositor->scheduleFrameForMonitor(Desktop::focusState()->monitor(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
// FIXME: This will be disabled during DnD operations because we do not exactly follow the spec
// xdg-popup grabs should be keyboard-only, while they are absolute in our case...
@ -492,8 +493,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
g_pSeatManager->setPointerFocus(nullptr, {});
if (refocus || g_pCompositor->m_lastWindow.expired()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
g_pCompositor->focusWindow(nullptr);
if (refocus || !Desktop::focusState()->window()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
Desktop::focusState()->rawWindowFocus(nullptr);
return;
}
@ -514,8 +515,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
bool allowKeyboardRefocus = true;
if (!refocus && g_pCompositor->m_lastFocus) {
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock());
if (!refocus && Desktop::focusState()->surface()) {
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
if (PLS && PLS->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
allowKeyboardRefocus = false;
@ -556,19 +557,19 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
}
if (FOLLOWMOUSE != 1 && !refocus) {
if (pFoundWindow != g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow.lock() &&
((pFoundWindow->m_isFloating && *PFLOATBEHAVIOR == 2) || (g_pCompositor->m_lastWindow->m_isFloating != pFoundWindow->m_isFloating && *PFLOATBEHAVIOR != 0))) {
if (pFoundWindow != Desktop::focusState()->window() && Desktop::focusState()->window() &&
((pFoundWindow->m_isFloating && *PFLOATBEHAVIOR == 2) || (Desktop::focusState()->window()->m_isFloating != pFoundWindow->m_isFloating && *PFLOATBEHAVIOR != 0))) {
// enter if change floating style
if (FOLLOWMOUSE != 3 && allowKeyboardRefocus)
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
} else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3)
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
if (pFoundWindow == g_pCompositor->m_lastWindow)
if (pFoundWindow == Desktop::focusState()->window())
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
if (FOLLOWMOUSE != 0 || pFoundWindow == g_pCompositor->m_lastWindow)
if (FOLLOWMOUSE != 0 || pFoundWindow == Desktop::focusState()->window())
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
if (g_pSeatManager->m_state.pointerFocus == foundSurface)
@ -578,26 +579,26 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
return; // don't enter any new surfaces
} else {
if (allowKeyboardRefocus && ((FOLLOWMOUSE != 3 && (*PMOUSEREFOCUS || m_lastMouseFocus.lock() != pFoundWindow)) || refocus)) {
if (m_lastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_lastWindow.lock() != pFoundWindow || g_pCompositor->m_lastFocus != foundSurface || refocus) {
if (m_lastMouseFocus.lock() != pFoundWindow || Desktop::focusState()->window() != pFoundWindow || Desktop::focusState()->surface() != foundSurface || refocus) {
m_lastMouseFocus = pFoundWindow;
// TODO: this looks wrong. When over a popup, it constantly is switching.
// Temp fix until that's figured out. Otherwise spams windowrule lookups and other shit.
if (m_lastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_lastWindow.lock() != pFoundWindow) {
if (m_lastMouseFocus.lock() != pFoundWindow || Desktop::focusState()->window() != pFoundWindow) {
if (m_mousePosDelta > *PFOLLOWMOUSETHRESHOLD || refocus) {
const bool hasNoFollowMouse = pFoundWindow && pFoundWindow->m_ruleApplicator->noFollowMouse().valueOrDefault();
if (refocus || !hasNoFollowMouse)
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
}
} else
g_pCompositor->focusSurface(foundSurface, pFoundWindow);
Desktop::focusState()->rawSurfaceFocus(foundSurface, pFoundWindow);
}
}
}
if (g_pSeatManager->m_state.keyboardFocus == nullptr)
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
m_lastFocusOnLS = false;
} else {
@ -608,7 +609,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
if (pFoundLayerSurface && (pFoundLayerSurface->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) && FOLLOWMOUSE != 3 &&
(allowKeyboardRefocus || pFoundLayerSurface->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)) {
g_pCompositor->focusSurface(foundSurface);
Desktop::focusState()->rawSurfaceFocus(foundSurface);
}
if (pFoundLayerSurface)
@ -762,7 +763,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
break;
if ((g_pSeatManager->m_mouse.expired() || !isConstrained()) /* No constraints */
&& (w && g_pCompositor->m_lastWindow.lock() != w) /* window should change */) {
&& (w && Desktop::focusState()->window() != w) /* window should change */) {
// a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
if (m_currentlyHeldButtons.size() == 1) {
@ -791,8 +792,8 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
// notify app if we didn't handle it
g_pSeatManager->sendPointerButton(e.timeMs, e.button, e.state);
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_lastMonitor && PMON)
g_pCompositor->setActiveMonitor(PMON);
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != Desktop::focusState()->monitor() && PMON)
Desktop::focusState()->rawMonitorFocus(PMON);
if (g_pSeatManager->m_seatGrab && e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
m_hardInput = true;
@ -1022,8 +1023,8 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
keeb->updateLEDs();
// in case m_lastFocus was set without a keyboard
if (m_keyboards.size() == 1 && g_pCompositor->m_lastFocus)
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_lastFocus.lock());
if (m_keyboards.size() == 1 && Desktop::focusState()->surface())
g_pSeatManager->setKeyboardFocus(Desktop::focusState()->surface());
}
void CInputManager::setKeyboardLayout() {
@ -1577,16 +1578,16 @@ bool CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
foundSurface = nullptr;
}
if (!foundSurface && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_workspace && g_pCompositor->m_lastWindow->m_workspace->isVisibleNotCovered()) {
if (!foundSurface && Desktop::focusState()->window() && Desktop::focusState()->window()->m_workspace && Desktop::focusState()->window()->m_workspace->isVisibleNotCovered()) {
// then the last focused window if we're on the same workspace as it
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
g_pCompositor->focusWindow(PLASTWINDOW);
const auto PLASTWINDOW = Desktop::focusState()->window();
Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
} else {
// otherwise fall back to a normal refocus.
if (foundSurface && !foundSurface->m_hlSurface->keyboardFocusable()) {
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
g_pCompositor->focusWindow(PLASTWINDOW);
const auto PLASTWINDOW = Desktop::focusState()->window();
Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
}
refocus();
@ -1615,7 +1616,7 @@ void CInputManager::unconstrainMouse() {
bool CInputManager::isConstrained() {
return std::ranges::any_of(m_constraints, [](auto const& c) {
const auto constraint = c.lock();
return constraint && constraint->isActive() && constraint->owner()->resource() == g_pCompositor->m_lastFocus;
return constraint && constraint->isActive() && constraint->owner()->resource() == Desktop::focusState()->surface();
});
}
@ -1623,7 +1624,7 @@ bool CInputManager::isLocked() {
if (!isConstrained())
return false;
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_lastFocus.lock());
const auto SURF = CWLSurface::fromResource(Desktop::focusState()->surface());
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
return CONSTRAINT && CONSTRAINT->isLocked();

View file

@ -1,6 +1,5 @@
#include "InputMethodRelay.hpp"
#include "InputManager.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/TextInputV3.hpp"
#include "../../protocols/TextInputV1.hpp"
#include "../../protocols/InputMethodV2.hpp"
@ -54,17 +53,17 @@ void CInputMethodRelay::onNewIME(SP<CInputMethodV2> pIME) {
Debug::log(LOG, "New input popup");
});
if (!g_pCompositor->m_lastFocus)
if (!Desktop::focusState()->surface())
return;
for (auto const& ti : m_textInputs) {
if (ti->client() != g_pCompositor->m_lastFocus->client())
if (ti->client() != Desktop::focusState()->surface()->client())
continue;
if (ti->isV3())
ti->enter(g_pCompositor->m_lastFocus.lock());
ti->enter(Desktop::focusState()->surface());
else
ti->onEnabled(g_pCompositor->m_lastFocus.lock());
ti->onEnabled(Desktop::focusState()->surface());
}
}
@ -73,11 +72,11 @@ void CInputMethodRelay::removePopup(CInputPopup* pPopup) {
}
CTextInput* CInputMethodRelay::getFocusedTextInput() {
if (!g_pCompositor->m_lastFocus)
if (!Desktop::focusState()->surface())
return nullptr;
for (auto const& ti : m_textInputs) {
if (ti->focusedSurface() == g_pCompositor->m_lastFocus)
if (ti->focusedSurface() == Desktop::focusState()->surface())
return ti.get();
}

View file

@ -1,8 +1,7 @@
#include "TextInput.hpp"
#include "../../defines.hpp"
#include "InputManager.hpp"
#include "../../protocols/TextInputV1.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/TextInputV3.hpp"
#include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/core/Compositor.hpp"
@ -31,8 +30,8 @@ void CTextInput::initCallbacks() {
g_pInputManager->m_relay.deactivateIME(this);
});
if (!g_pCompositor->m_lastFocus.expired() && g_pCompositor->m_lastFocus->client() == INPUT->client())
enter(g_pCompositor->m_lastFocus.lock());
if (Desktop::focusState()->surface() && Desktop::focusState()->surface()->client() == INPUT->client())
enter(Desktop::focusState()->surface());
} else {
const auto INPUT = m_v1Input.lock();
@ -60,7 +59,7 @@ void CTextInput::onEnabled(SP<CWLSurfaceResource> surfV1) {
// v1 only, map surface to PTI
if (!isV3()) {
if (g_pCompositor->m_lastFocus != surfV1 || !m_v1Input->m_active)
if (Desktop::focusState()->surface() != surfV1 || !m_v1Input->m_active)
return;
enter(surfV1);

View file

@ -3,11 +3,11 @@
#include "../../protocols/SessionLock.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/LayerSurface.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../helpers/Monitor.hpp"
#include "../../devices/ITouch.hpp"
#include "../SeatManager.hpp"
#include "managers/animation/AnimationManager.hpp"
#include "../HookSystemManager.hpp"
#include "debug/Log.hpp"
#include "UnifiedWorkspaceSwipeGesture.hpp"
@ -26,7 +26,7 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
auto PMONITOR = g_pCompositor->getMonitorFromName(!e.device->m_boundOutput.empty() ? e.device->m_boundOutput : "");
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_lastMonitor.lock();
PMONITOR = PMONITOR ? PMONITOR : Desktop::focusState()->monitor();
const auto TOUCH_COORDS = PMONITOR->m_position + (e.pos * PMONITOR->m_size);

View file

@ -1,6 +1,7 @@
#include "UnifiedWorkspaceSwipeGesture.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../render/Renderer.hpp"
#include "InputManager.hpp"
@ -12,18 +13,18 @@ void CUnifiedWorkspaceSwipeGesture::begin() {
if (isGestureInProgress())
return;
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
Debug::log(LOG, "CUnifiedWorkspaceSwipeGesture::begin: Starting a swipe from {}", PWORKSPACE->m_name);
m_workspaceBegin = PWORKSPACE;
m_delta = 0;
m_monitor = g_pCompositor->m_lastMonitor;
m_monitor = Desktop::focusState()->monitor();
m_avgSpeed = 0;
m_speedPoints = 0;
if (PWORKSPACE->m_hasFullscreenWindow) {
for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
for (auto const& ls : Desktop::focusState()->monitor()->m_layerSurfaceLayers[2]) {
*ls->m_alpha = 1.f;
}
}
@ -307,7 +308,7 @@ void CUnifiedWorkspaceSwipeGesture::end() {
g_pInputManager->refocus();
// apply alpha
for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
for (auto const& ls : Desktop::focusState()->monitor()->m_layerSurfaceLayers[2]) {
*ls->m_alpha = pSwitchedTo->m_hasFullscreenWindow && pSwitchedTo->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
}
}

View file

@ -7,6 +7,7 @@
#include "../../../../managers/eventLoop/EventLoopManager.hpp"
#include "../../../../managers/eventLoop/EventLoopTimer.hpp"
#include "../../../../config/ConfigValue.hpp"
#include "../../../../desktop/state/FocusState.hpp"
constexpr const float MAX_DISTANCE = 200.F;
@ -27,7 +28,7 @@ static float lerpVal(const float& from, const float& to, const float& t) {
void CCloseTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow;
m_window = Desktop::focusState()->window();
if (!m_window)
return;

View file

@ -1,8 +1,9 @@
#include "FloatGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../desktop/Window.hpp"
constexpr const float MAX_DISTANCE = 250.F;
@ -29,7 +30,7 @@ CFloatTrackpadGesture::CFloatTrackpadGesture(const std::string_view& data) {
void CFloatTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow;
m_window = Desktop::focusState()->window();
if (!m_window)
return;

View file

@ -1,6 +1,7 @@
#include "FullscreenGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp"
#include "../../../animation/DesktopAnimationManager.hpp"
@ -29,7 +30,7 @@ CFullscreenTrackpadGesture::CFullscreenTrackpadGesture(const std::string_view& m
void CFullscreenTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow;
m_window = Desktop::focusState()->window();
if (!m_window)
return;

View file

@ -1,13 +1,14 @@
#include "MoveGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../desktop/Window.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp"
void CMoveTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow;
m_window = Desktop::focusState()->window();
m_lastDelta = {};
}

View file

@ -1,13 +1,14 @@
#include "ResizeGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../desktop/Window.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp"
void CResizeTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow;
m_window = Desktop::focusState()->window();
}
void CResizeTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {

View file

@ -1,7 +1,7 @@
#include "SpecialWorkspaceGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp"
#include <hyprutils/memory/Casts.hpp>
@ -36,7 +36,7 @@ void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBeg
if (m_specialWorkspace) {
m_animatingOut = m_specialWorkspace->isVisible();
m_monitor = m_animatingOut ? m_specialWorkspace->m_monitor : g_pCompositor->m_lastMonitor;
m_monitor = m_animatingOut ? m_specialWorkspace->m_monitor : Desktop::focusState()->monitor();
if (!m_monitor)
return;
@ -44,7 +44,7 @@ void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBeg
if (!m_animatingOut)
m_monitor->setSpecialWorkspace(m_specialWorkspace);
} else {
m_monitor = g_pCompositor->m_lastMonitor;
m_monitor = Desktop::focusState()->monitor();
if (!m_monitor)
return;

View file

@ -1,7 +1,7 @@
#include "WorkspaceSwipeGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../managers/input/InputManager.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp"
#include "../../UnifiedWorkspaceSwipeGesture.hpp"
@ -16,7 +16,7 @@ void CWorkspaceSwipeGesture::begin(const ITrackpadGesture::STrackpadGestureBegin
int onMonitor = 0;
for (auto const& w : g_pCompositor->getWorkspaces()) {
if (w->m_monitor == g_pCompositor->m_lastMonitor && !g_pCompositor->isWorkspaceSpecial(w->m_id))
if (w->m_monitor == Desktop::focusState()->monitor() && !g_pCompositor->isWorkspaceSpecial(w->m_id))
onMonitor++;
}

View file

@ -22,6 +22,9 @@ CExtWorkspaceGroupResource::CExtWorkspaceGroupResource(WP<CExtWorkspaceManagerRe
m_resource->sendCapabilities(sc<extWorkspaceGroupHandleV1GroupCapabilities>(0));
if (!PROTO::outputs.contains(m_monitor->m_name))
return;
const auto& output = PROTO::outputs.at(m_monitor->m_name);
if (auto resource = output->outputResourceFrom(m_resource->client()))

View file

@ -3,6 +3,7 @@
#include <hyprland-focus-grab-v1.hpp>
#include "../managers/input/InputManager.hpp"
#include "../managers/SeatManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "core/Compositor.hpp"
#include <cstdint>
#include <wayland-server.h>
@ -104,7 +105,7 @@ void CFocusGrab::refocusKeyboard() {
}
if (surface)
g_pCompositor->focusSurface(surface);
Desktop::focusState()->rawSurfaceFocus(surface);
else
LOGM(ERR, "CFocusGrab::refocusKeyboard called with no committed surfaces. This should never happen.");
}

View file

@ -1,9 +1,10 @@
#include "ForeignToplevelWlr.hpp"
#include "core/Output.hpp"
#include <algorithm>
#include "../Compositor.hpp"
#include "managers/input/InputManager.hpp"
#include "protocols/core/Output.hpp"
#include "render/Renderer.hpp"
#include "../managers/input/InputManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp"
#include "../managers/EventManager.hpp"
@ -50,7 +51,7 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHand
if (PWINDOW->m_workspace != monitor->m_activeWorkspace) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, monitor->m_activeWorkspace);
g_pCompositor->setActiveMonitor(monitor);
Desktop::focusState()->rawMonitorFocus(monitor);
}
}
}
@ -178,7 +179,7 @@ void CForeignToplevelHandleWlr::sendState() {
wl_array state;
wl_array_init(&state);
if (PWINDOW == g_pCompositor->m_lastWindow) {
if (PWINDOW == Desktop::focusState()->window()) {
auto p = sc<uint32_t*>(wl_array_add(&state, sizeof(uint32_t)));
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
}
@ -216,7 +217,7 @@ CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP<CZwlrForeignToplevelMa
onMap(w);
}
m_lastFocus = g_pCompositor->m_lastWindow;
m_lastFocus = Desktop::focusState()->window();
}
void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) {

View file

@ -1,7 +1,8 @@
#include "InputMethodV2.hpp"
#include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../managers/SeatManager.hpp"
#include "../devices/IKeyboard.hpp"
#include "../helpers/MiscFunctions.hpp"
#include <sys/mman.h>
#include "core/Compositor.hpp"
#include <cstring>
@ -96,8 +97,8 @@ CInputMethodPopupV2::CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_,
m_listeners.destroySurface.reset();
m_listeners.commitSurface.reset();
if (g_pCompositor->m_lastFocus == m_surface)
g_pCompositor->m_lastFocus.reset();
if (Desktop::focusState()->surface() == m_surface)
Desktop::focusState()->surface().reset();
m_surface.reset();
});

View file

@ -1,6 +1,7 @@
#include "PointerConstraints.hpp"
#include "../desktop/WLSurface.hpp"
#include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../desktop/Window.hpp"
#include "../config/ConfigValue.hpp"
#include "../managers/SeatManager.hpp"
#include "core/Compositor.hpp"
@ -242,7 +243,7 @@ void CPointerConstraintsProtocol::onNewConstraint(SP<CPointerConstraint> constra
g_pInputManager->m_constraints.emplace_back(constraint);
if (g_pCompositor->m_lastFocus == OWNER->resource())
if (Desktop::focusState()->surface() == OWNER->resource())
constraint->activate();
}

View file

@ -1,5 +1,4 @@
#include "SessionLock.hpp"
#include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "FractionalScale.hpp"
#include "LockNotify.hpp"
@ -7,6 +6,7 @@
#include "core/Output.hpp"
#include "../helpers/Monitor.hpp"
#include "../render/Renderer.hpp"
#include "../desktop/state/FocusState.hpp"
CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, SP<CWLSurfaceResource> surface_, PHLMONITOR pMonitor_, WP<CSessionLock> owner_) :
m_resource(resource_), m_sessionLock(owner_), m_surface(surface_), m_monitor(pMonitor_) {
@ -51,15 +51,19 @@ CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_,
m_surface->unmap();
m_listeners.surfaceCommit.reset();
m_listeners.surfaceDestroy.reset();
if (g_pCompositor->m_lastFocus == m_surface)
g_pCompositor->m_lastFocus.reset();
if (Desktop::focusState()->surface() == m_surface)
Desktop::focusState()->surface().reset();
m_surface.reset();
});
if (m_monitor)
if (m_monitor) {
PROTO::fractional->sendScale(surface_, m_monitor->m_scale);
if (m_surface)
m_surface->enter(m_monitor.lock());
}
sendConfigure();
m_listeners.monitorMode = m_monitor->m_events.modeChanged.listen([this] { sendConfigure(); });

View file

@ -1,6 +1,7 @@
#include "ShortcutsInhibit.hpp"
#include <algorithm>
#include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "core/Compositor.hpp"
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf) : m_resource(resource_), m_surface(surf) {
@ -67,14 +68,14 @@ void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitMa
}
bool CKeyboardShortcutsInhibitProtocol::isInhibited() {
if (!g_pCompositor->m_lastFocus)
if (!Desktop::focusState()->surface())
return false;
if (const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_lastFocus.lock()); PWINDOW && PWINDOW->m_ruleApplicator->noShortcutsInhibit().valueOrDefault())
if (const auto PWINDOW = g_pCompositor->getWindowFromSurface(Desktop::focusState()->surface()); PWINDOW && PWINDOW->m_ruleApplicator->noShortcutsInhibit().valueOrDefault())
return false;
for (auto const& in : m_inhibitors) {
if (in->surface() != g_pCompositor->m_lastFocus)
if (in->surface() != Desktop::focusState()->surface())
continue;
return true;

View file

@ -550,13 +550,6 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) {
nullptr);
}
if (m_current.updated.bits.damage) {
// damage is always relative to the current commit
m_current.updated.bits.damage = false;
m_current.damage.clear();
m_current.bufferDamage.clear();
}
// release the buffer if it's synchronous (SHM) as updateSynchronousTexture() has copied the buffer data to a GPU tex
// if it doesn't have a role, we can't release it yet, in case it gets turned into a cursor.
if (m_current.buffer && m_current.buffer->isSynchronous() && m_role->role() != SURFACE_ROLE_UNASSIGNED)

View file

@ -7,8 +7,8 @@
#if defined(__linux__)
#include <linux/dma-buf.h>
#include <linux/sync_file.h>
#include <sys/ioctl.h>
#endif
#include <sys/ioctl.h>
using namespace Hyprutils::OS;

View file

@ -65,11 +65,8 @@ void SSurfaceState::reset() {
lockMask = LOCK_REASON_NONE;
}
void SSurfaceState::updateFrom(SSurfaceState& ref, bool merge) {
if (merge)
updated.all |= ref.updated.all;
else
updated = ref.updated;
void SSurfaceState::updateFrom(SSurfaceState& ref) {
updated = ref.updated;
if (ref.updated.bits.buffer) {
buffer = ref.buffer;
@ -81,6 +78,10 @@ void SSurfaceState::updateFrom(SSurfaceState& ref, bool merge) {
if (ref.updated.bits.damage) {
damage = ref.damage;
bufferDamage = ref.bufferDamage;
} else {
// damage is always relative to the current commit
damage.clear();
bufferDamage.clear();
}
if (ref.updated.bits.input)

View file

@ -89,7 +89,7 @@ struct SSurfaceState {
void updateSynchronousTexture(SP<CTexture> lastTexture);
// helpers
CRegion accumulateBufferDamage(); // transforms state.damage and merges it into state.bufferDamage
void updateFrom(SSurfaceState& ref, bool merge = false); // updates this state based on a reference state.
void reset(); // resets pending state after commit
CRegion accumulateBufferDamage(); // transforms state.damage and merges it into state.bufferDamage
void updateFrom(SSurfaceState& ref); // updates this state based on a reference state.
void reset(); // resets pending state after commit
};

View file

@ -63,28 +63,12 @@ auto CSurfaceStateQueue::find(const WP<SSurfaceState>& state) -> std::deque<UP<S
}
void CSurfaceStateQueue::tryProcess() {
if (m_queue.empty())
return;
while (!m_queue.empty()) {
auto& front = m_queue.front();
if (front->lockMask != LOCK_REASON_NONE)
return;
auto front = m_queue.begin();
if (front->get()->lockMask != LOCK_REASON_NONE)
return;
auto next = std::next(front);
if (next == m_queue.end()) {
m_surface->commitState(**front);
m_surface->commitState(*front);
m_queue.pop_front();
return;
}
while (!m_queue.empty() && next != m_queue.end() && next->get()->lockMask == LOCK_REASON_NONE && !next->get()->updated.bits.buffer) {
next->get()->updateFrom(**front, true);
m_queue.pop_front();
front = m_queue.begin();
next = std::next(front);
}
m_surface->commitState(**front);
m_queue.pop_front();
}

View file

@ -14,6 +14,7 @@
#include "../config/ConfigManager.hpp"
#include "../managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/ColorManagement.hpp"
@ -424,7 +425,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmRenderNode.fd >
auto PMONITOR = g_pCompositor->getMonitorFromName(!E.device->m_boundOutput.empty() ? E.device->m_boundOutput : "");
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_lastMonitor.lock();
PMONITOR = PMONITOR ? PMONITOR : Desktop::focusState()->monitor();
const auto TOUCH_COORDS = PMONITOR->m_position + (E.pos * PMONITOR->m_size);

View file

@ -14,6 +14,7 @@
#include "../managers/LayoutManager.hpp"
#include "../desktop/Window.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/SessionLock.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp"
@ -168,7 +169,7 @@ CHyprRenderer::CHyprRenderer() {
w->m_wlSurface->resource()->frame(Time::steadyNow());
auto FEEDBACK = makeUnique<CQueuedPresentationData>(w->m_wlSurface->resource());
FEEDBACK->attachMonitor(g_pCompositor->m_lastMonitor.lock());
FEEDBACK->attachMonitor(Desktop::focusState()->monitor());
FEEDBACK->discarded();
PROTO::presentation->queueData(std::move(FEEDBACK));
}
@ -403,7 +404,7 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo
continue;
// render active window after all others of this pass
if (w == g_pCompositor->m_lastWindow) {
if (w == Desktop::focusState()->window()) {
lastWindow = w.lock();
continue;
}
@ -612,6 +613,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
renderdata.surfaceCounter = 0;
pWindow->m_wlSurface->resource()->breadthfirst(
[this, &renderdata, &pWindow](SP<CWLSurfaceResource> s, const Vector2D& offset, void* data) {
if (!s->m_current.texture)
return;
if (s->m_current.size.x < 1 || s->m_current.size.y < 1)
return;
renderdata.localPos = offset;
renderdata.texture = s->m_current.texture;
renderdata.surface = s;
@ -685,6 +692,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const T
popup->m_wlSurface->resource()->breadthfirst(
[this, &renderdata](SP<CWLSurfaceResource> s, const Vector2D& offset, void* data) {
if (!s->m_current.texture)
return;
if (s->m_current.size.x < 1 || s->m_current.size.y < 1)
return;
renderdata.localPos = offset;
renderdata.texture = s->m_current.texture;
renderdata.surface = s;
@ -765,6 +778,12 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, const Time::s
if (!popups)
pLayer->m_surface->resource()->breadthfirst(
[this, &renderdata, &pLayer](SP<CWLSurfaceResource> s, const Vector2D& offset, void* data) {
if (!s->m_current.texture)
return;
if (s->m_current.size.x < 1 || s->m_current.size.y < 1)
return;
renderdata.localPos = offset;
renderdata.texture = s->m_current.texture;
renderdata.surface = s;
@ -785,10 +804,18 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, const Time::s
if (!popup->m_wlSurface || !popup->m_wlSurface->resource() || !popup->m_mapped)
return;
const auto SURF = popup->m_wlSurface->resource();
if (!SURF->m_current.texture)
return;
if (SURF->m_current.size.x < 1 || SURF->m_current.size.y < 1)
return;
Vector2D pos = popup->coordsRelativeToParent();
renderdata.localPos = pos;
renderdata.texture = popup->m_wlSurface->resource()->m_current.texture;
renderdata.surface = popup->m_wlSurface->resource();
renderdata.texture = SURF->m_current.texture;
renderdata.surface = SURF;
renderdata.mainSurface = false;
m_renderPass.add(makeUnique<CSurfacePassElement>(renderdata));
renderdata.surfaceCounter++;
@ -821,6 +848,12 @@ void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, con
SURF->breadthfirst(
[this, &renderdata, &SURF](SP<CWLSurfaceResource> s, const Vector2D& offset, void* data) {
if (!s->m_current.texture)
return;
if (s->m_current.size.x < 1 || s->m_current.size.y < 1)
return;
renderdata.localPos = offset;
renderdata.texture = s->m_current.texture;
renderdata.surface = s;
@ -842,6 +875,12 @@ void CHyprRenderer::renderSessionLockSurface(WP<SSessionLockSurface> pSurface, P
renderdata.surface->breadthfirst(
[this, &renderdata, &pSurface](SP<CWLSurfaceResource> s, const Vector2D& offset, void* data) {
if (!s->m_current.texture)
return;
if (s->m_current.size.x < 1 || s->m_current.size.y < 1)
return;
renderdata.localPos = offset;
renderdata.texture = s->m_current.texture;
renderdata.surface = s;
@ -1156,7 +1195,7 @@ void CHyprRenderer::calculateUVForSurface(PHLWINDOW pWindow, SP<CWLSurfaceResour
// to let the apps know to NOT add CSD. Also if source is there.
// there is no way to fix this if that's the case
const auto MONITOR_WL_SCALE = std::ceil(pMonitor->m_scale);
const bool SCALE_UNAWARE = MONITOR_WL_SCALE > 1 && (MONITOR_WL_SCALE == pSurface->m_current.scale || !pSurface->m_current.viewport.hasDestination);
const bool SCALE_UNAWARE = pMonitor->m_scale != 1.f && (MONITOR_WL_SCALE == pSurface->m_current.scale || !pSurface->m_current.viewport.hasDestination);
const auto EXPECTED_SIZE = getSurfaceExpectedSize(pWindow, pSurface, pMonitor, main).value_or((projSize * pMonitor->m_scale).round());
const auto RATIO = projSize / EXPECTED_SIZE;
@ -1247,6 +1286,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
if (!g_pCompositor->m_sessionActive)
return;
if (g_pAnimationManager)
g_pAnimationManager->frameTick();
if (pMonitor->m_id == m_mostHzMonitor->m_id ||
*PVFR == 1) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
@ -1366,7 +1408,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
renderLockscreen(pMonitor, NOW, renderBox);
if (pMonitor == g_pCompositor->m_lastMonitor) {
if (pMonitor == Desktop::focusState()->monitor()) {
g_pHyprNotificationOverlay->draw(pMonitor);
g_pHyprError->draw();
}
@ -1854,7 +1896,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const MONITORID& monitor) {
CBox usableArea = {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == PMONITOR->m_self) {
if (g_pHyprError->active() && Desktop::focusState()->monitor() == PMONITOR->m_self) {
const auto HEIGHT = g_pHyprError->height();
if (*BAR_POSITION == 0) {
PMONITOR->m_reservedTopLeft.y = HEIGHT;
@ -2531,6 +2573,12 @@ void CHyprRenderer::makeSnapshot(WP<CPopup> popup) {
popup->m_wlSurface->resource()->breadthfirst(
[this, &renderdata](SP<CWLSurfaceResource> s, const Vector2D& offset, void* data) {
if (!s->m_current.texture)
return;
if (s->m_current.size.x < 1 || s->m_current.size.y < 1)
return;
renderdata.localPos = offset;
renderdata.texture = s->m_current.texture;
renderdata.surface = s;

View file

@ -1,6 +1,7 @@
#include "CHyprGroupBarDecoration.hpp"
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "managers/LayoutManager.hpp"
#include <ranges>
#include <pango/pangocairo.h>
@ -160,7 +161,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
const auto* const PCOLACTIVE = GROUPLOCKED ? GROUPCOLACTIVELOCKED : GROUPCOLACTIVE;
const auto* const PCOLINACTIVE = GROUPLOCKED ? GROUPCOLINACTIVELOCKED : GROUPCOLINACTIVE;
CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_lastWindow.lock() ? PCOLACTIVE->m_colors[0] : PCOLINACTIVE->m_colors[0];
CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == Desktop::focusState()->window() ? PCOLACTIVE->m_colors[0] : PCOLINACTIVE->m_colors[0];
color.a *= a;
if (!rect.empty()) {
@ -195,8 +196,8 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
if (!rect.empty()) {
if (*PGRADIENTS) {
const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window() ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
if (GRADIENTTEX->m_texID) {
CTexPassElement::SRenderData data;
data.tex = GRADIENTTEX;
@ -234,7 +235,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
.get();
SP<CTexture> titleTex;
if (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow)
if (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window())
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedActive : pTitleTex->m_texActive;
else
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedInactive : pTitleTex->m_texInactive;
@ -308,10 +309,10 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float
static void renderGradientTo(SP<CTexture> tex, CGradientValueData* grad) {
if (!g_pCompositor->m_lastMonitor)
if (!Desktop::focusState()->monitor())
return;
const Vector2D& bufferSize = g_pCompositor->m_lastMonitor->m_pixelSize;
const Vector2D& bufferSize = Desktop::focusState()->monitor()->m_pixelSize;
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE);
@ -415,7 +416,7 @@ bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
g_pInputManager->m_currentlyDraggedWindow = pWindow;
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->rawWindowFocus(pWindow);
return true;
}
@ -529,7 +530,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
const auto STACKPAD = *PSTACKED && (BARRELATIVEY - (m_barHeight + *POUTERGAP) * WINDOWINDEX < *POUTERGAP);
if (TABPAD || STACKPAD) {
if (!g_pCompositor->isWindowActive(m_window.lock()))
g_pCompositor->focusWindow(m_window.lock());
Desktop::focusState()->rawWindowFocus(m_window.lock());
return true;
}
@ -539,7 +540,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
pWindow->setGroupCurrent(pWindow);
if (!g_pCompositor->isWindowActive(pWindow) && *PFOLLOWMOUSE != 3)
g_pCompositor->focusWindow(pWindow);
Desktop::focusState()->rawWindowFocus(pWindow);
if (pWindow->m_isFloating)
g_pCompositor->changeWindowZOrder(pWindow, true);

View file

@ -2,12 +2,13 @@
#include "../OpenGL.hpp"
#include <algorithm>
#include <ranges>
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../desktop/WLSurface.hpp"
#include "../../managers/SeatManager.hpp"
#include "../../managers/eventLoop/EventLoopManager.hpp"
#include "../../render/Renderer.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/core/Compositor.hpp"
bool CRenderPass::empty() const {
@ -242,8 +243,8 @@ void CRenderPass::renderDebugData() {
renderHLSurface(m_debugData.keyboardFocusText, g_pSeatManager->m_state.keyboardFocus.lock(), Colors::PURPLE.modifyA(0.1F));
renderHLSurface(m_debugData.pointerFocusText, g_pSeatManager->m_state.pointerFocus.lock(), Colors::ORANGE.modifyA(0.1F));
if (g_pCompositor->m_lastWindow)
renderHLSurface(m_debugData.lastWindowText, g_pCompositor->m_lastWindow->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F));
if (Desktop::focusState()->window())
renderHLSurface(m_debugData.lastWindowText, Desktop::focusState()->window()->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F));
if (g_pSeatManager->m_state.pointerFocus) {
if (g_pSeatManager->m_state.pointerFocus->m_current.input.intersect(CBox{{}, g_pSeatManager->m_state.pointerFocus->m_current.size}).getExtents().size() !=

View file

@ -20,6 +20,7 @@
#include "../managers/ANRManager.hpp"
#include "../protocols/XWaylandShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
using Hyprutils::Memory::CUniquePointer;
using namespace Hyprutils::OS;
@ -1037,7 +1038,7 @@ void CXWM::activateSurface(SP<CXWaylandSurface> surf, bool activate) {
if ((surf == m_focusedSurface && activate) || (surf && surf->m_overrideRedirect))
return;
if (!surf || (!activate && g_pCompositor->m_lastWindow && !g_pCompositor->m_lastWindow->m_isX11)) {
if (!surf || (!activate && Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isX11)) {
setActiveWindow(XCB_WINDOW_NONE);
focusWindow(nullptr);
} else {