mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-20 07:30:05 +01:00
Add config option to focus master window on close in master layout
- Add master:focus_master_on_close config option (default: 0) - When enabled, closing a master window focuses the next master window - Maintains backward compatibility with existing configs - Improve workflow continuity for master layout users Fixes usability issue where closing master windows could focus stack windows instead of staying in the master area.
This commit is contained in:
parent
cf7e3aa448
commit
57be5317ee
4 changed files with 46 additions and 6 deletions
|
|
@ -1122,7 +1122,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "misc:force_default_wallpaper",
|
.value = "misc:force_default_wallpaper",
|
||||||
.description = "Enforce any of the 3 default wallpapers. Setting this to 0 or 1 disables the anime background. -1 means “random”. [-1/0/1/2]",
|
.description = "Enforce any of the 3 default wallpapers. Setting this to 0 or 1 disables the anime background. -1 means "random". [-1/0/1/2]",
|
||||||
.type = CONFIG_OPTION_INT,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SRangeData{-1, -1, 2},
|
.data = SConfigOptionDescription::SRangeData{-1, -1, 2},
|
||||||
},
|
},
|
||||||
|
|
@ -1196,7 +1196,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "misc:swallow_exception_regex",
|
.value = "misc:swallow_exception_regex",
|
||||||
.description = "The title regex to be used for windows that should not be swallowed by the windows specified in swallow_regex (e.g. wev). The regex is matched against the "
|
.description = "The title regex to be used for windows that should not be swallowed by the windows specified in swallow_regex (e.g. wev). The regex is matched against the "
|
||||||
"parent (e.g. Kitty) window’s title on the assumption that it changes to whatever process it’s running.",
|
"parent (e.g. Kitty) window's title on the assumption that it changes to whatever process it's running.",
|
||||||
.type = CONFIG_OPTION_STRING_SHORT,
|
.type = CONFIG_OPTION_STRING_SHORT,
|
||||||
.data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET?
|
.data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET?
|
||||||
},
|
},
|
||||||
|
|
@ -1322,7 +1322,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "binds:workspace_back_and_forth",
|
.value = "binds:workspace_back_and_forth",
|
||||||
.description = "If enabled, an attempt to switch to the currently focused workspace will instead switch to the previous workspace. Akin to i3’s auto_back_and_forth.",
|
.description = "If enabled, an attempt to switch to the currently focused workspace will instead switch to the previous workspace. Akin to i3's auto_back_and_forth.",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
},
|
},
|
||||||
|
|
@ -1334,7 +1334,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "binds:allow_workspace_cycles",
|
.value = "binds:allow_workspace_cycles",
|
||||||
.description = "If enabled, workspaces don’t forget their previous workspace, so cycles can be created by switching to the first workspace in a sequence, then endlessly "
|
.description = "If enabled, workspaces don't forget their previous workspace, so cycles can be created by switching to the first workspace in a sequence, then endlessly "
|
||||||
"going to the previous workspace.",
|
"going to the previous workspace.",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
|
|
@ -1520,7 +1520,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:inactive_timeout",
|
.value = "cursor:inactive_timeout",
|
||||||
.description = "in seconds, after how many seconds of cursor’s inactivity to hide it. Set to 0 for never.",
|
.description = "in seconds, after how many seconds of cursor's inactivity to hide it. Set to 0 for never.",
|
||||||
.type = CONFIG_OPTION_INT,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SRangeData{0, 0, 20},
|
.data = SConfigOptionDescription::SRangeData{0, 0, 20},
|
||||||
},
|
},
|
||||||
|
|
@ -1905,7 +1905,13 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "master:always_keep_position",
|
.value = "master:always_keep_position",
|
||||||
.description = "whether to keep the master window in its configured position when there are no slave windows",
|
.description = "If enabled, the master window will always keep its position and size even when it's the only window on the workspace.",
|
||||||
|
.type = CONFIG_OPTION_BOOL,
|
||||||
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
|
},
|
||||||
|
SConfigOptionDescription{
|
||||||
|
.value = "master:focus_master_on_close",
|
||||||
|
.description = "If enabled, when a master window is closed, focus will automatically shift to the next master window instead of potentially focusing a stack window.",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -615,6 +615,7 @@ CConfigManager::CConfigManager() {
|
||||||
registerConfigVar("master:smart_resizing", Hyprlang::INT{1});
|
registerConfigVar("master:smart_resizing", Hyprlang::INT{1});
|
||||||
registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1});
|
registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1});
|
||||||
registerConfigVar("master:always_keep_position", Hyprlang::INT{0});
|
registerConfigVar("master:always_keep_position", Hyprlang::INT{0});
|
||||||
|
registerConfigVar("master:focus_master_on_close", Hyprlang::INT{0});
|
||||||
|
|
||||||
registerConfigVar("animations:enabled", Hyprlang::INT{1});
|
registerConfigVar("animations:enabled", Hyprlang::INT{1});
|
||||||
registerConfigVar("animations:first_launch_animation", Hyprlang::INT{1});
|
registerConfigVar("animations:first_launch_animation", Hyprlang::INT{1});
|
||||||
|
|
|
||||||
|
|
@ -1484,3 +1484,34 @@ void CHyprMasterLayout::onEnable() {
|
||||||
void CHyprMasterLayout::onDisable() {
|
void CHyprMasterLayout::onDisable() {
|
||||||
m_masterNodesData.clear();
|
m_masterNodesData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PHLWINDOW CHyprMasterLayout::getNextWindowCandidate(PHLWINDOW pWindow) {
|
||||||
|
static auto PFOCUSMASTERONCLOSE = CConfigValue<Hyprlang::INT>("master:focus_master_on_close");
|
||||||
|
|
||||||
|
// If the config is enabled and we have a valid window that was closed
|
||||||
|
if (*PFOCUSMASTERONCLOSE && pWindow && pWindow->m_workspace) {
|
||||||
|
const auto PNODE = getNodeFromWindow(pWindow);
|
||||||
|
|
||||||
|
// If the closed window was a master window, try to focus the next master window
|
||||||
|
if (PNODE && PNODE->isMaster) {
|
||||||
|
const auto WORKSPACEID = pWindow->workspaceID();
|
||||||
|
|
||||||
|
// Find the next master window in the same workspace
|
||||||
|
for (auto& nd : m_masterNodesData) {
|
||||||
|
if (nd.workspaceID == WORKSPACEID && nd.isMaster && nd.pWindow.lock() != pWindow && nd.pWindow.lock() && nd.pWindow.lock()->m_isMapped) {
|
||||||
|
return nd.pWindow.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no other master window found, try to find any master window in the workspace
|
||||||
|
for (auto& nd : m_masterNodesData) {
|
||||||
|
if (nd.workspaceID == WORKSPACEID && nd.isMaster && nd.pWindow.lock() && nd.pWindow.lock()->m_isMapped) {
|
||||||
|
return nd.pWindow.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to default behavior
|
||||||
|
return IHyprLayout::getNextWindowCandidate(pWindow);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@ class CHyprMasterLayout : public IHyprLayout {
|
||||||
virtual void onEnable();
|
virtual void onEnable();
|
||||||
virtual void onDisable();
|
virtual void onDisable();
|
||||||
|
|
||||||
|
virtual PHLWINDOW getNextWindowCandidate(PHLWINDOW) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<SMasterNodeData> m_masterNodesData;
|
std::list<SMasterNodeData> m_masterNodesData;
|
||||||
std::vector<SMasterWorkspaceData> m_masterWorkspacesData;
|
std::vector<SMasterWorkspaceData> m_masterWorkspacesData;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue