fullscreen: Refactor fullscreen logic from the ground up; Fullscreen Controller and Fullscreen Handlers, better handle defaut and layout handled FS, add ability to default FS windows even on layout handled FS workspaces, fix many bugs related to fullscreen - #14705
Conversation
|
Hello and thank you for making a PR to Hyprland! Please check the PR Guidelines and make sure your PR follows them. If your code can be tested, please always add tests. See more here. beep boop, I'm just a bot. A real human will review your PR soon. |
d465531 to
6035f51
Compare
9a4a4b2 to
e294ccc
Compare
c43950e to
aa16287
Compare
8bc7257 to
5ecdd8d
Compare
58706b1 to
6b8b51b
Compare
|
Will change how 1 - All newly created windows start with |
|
In Scrolling Layout: when a window that is the last/only window in a column is floating and the layout scrolls to a FS window, that window is left ontop of the tiled FS window. I think this is a good idea, as it's unlikely that the user would want to lose that window they just floated. |
|
It's almost done. Only some edge case bug fixes, polish, and cleanup remains unless I also add in this PR the ability to default FS windows in workspaces with layout managed FS's available. Just about everything else works now, so please help test! |
1a3cbae to
eaaa5a7
Compare
|
I'm marking this as ready for now. Mainly to hopefully get more ppl testing and have vax have a look over the code if he approves of the general changes. Still need to do some comment cleanup, need to look into some hyprtests, and play with windowrules a bit to see if all is good; but the broad strokes should be gtg. Hopefully more people help test if it's marked as ready too. |
β¦onsistency, fix spelling mistake, add null check for handlers to `getFsHandlersForWorkspace`, clarification comment for `getCurrentWorkspace()`, format
|
done |
|
@codex review please |
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5448d24d5
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
VRR in def handler FS layout handled state preserved on FS window unmap Groups adding to group maintains group's layout FS handler state
|
done |
|
@codex review please |
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b595f07164
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Reviewed. Actually wait i have an idea for the first one let me try to handle that. The other two are not bugs |
Scrolling already does because its pos setting happens in its recalc.
|
Done. I really want to avoid slapping a |
|
@codex review please |
yeah, but you could've just added some rechec() but oh well this works ig |
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6de59cedfc
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Initalise Vars - respect VRR config opts in recalc setting VRR if scrolling onto or have a new FS window
|
done |
|
@codex review please |
|
shame it cant do more at once |
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25c2b4e0de
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Repeated (#14705 (comment)). Guess it's a good sign that it only gave this I'm unsatisfied with pos setting with changing work area so I'll redo that. Otherwise, if the oracle gives its blessings, merge at your discretion. edit: done. p.s. |
Replace all calls to default handler from algorithms with controller() calls that include error correction logic - Scrolling is an exception as its handling is radically different Extract repeated code into helper Fix minor bugs
Adjust test to reflect this change

Describe your PR, what does it fix/add?
This PR seeks to:
Note: Layouts use their Fullscreen Handlers for their 'unique' fullscreen management. e.g. with scrolling you can scroll onto a FS window. When you do this, it doesn't call the controller but calls its Fullscreen Handler; the logic for managing multiple FS windows in a workspace is unique to scrolling and the logic/attributes/methods should be isolated to scrolling specific classes
Note: Handlers keep a list of FS windows in their 'area of responsibility (workspace)'.
CWindowandCWorkspaceno longer have theirm_fullscreenStateandm_hasFullscreenWindowattributes: these values returned to lua are obtained from the FS handlers that handle those windows/workspacesRenames/Removals/Misc. Behaviour Changes
m_createdOverFullscreen-->m_allowedOverFullscreento be more descriptive of its function.m_allowedOverFullscreenlogic: all windows when they are not hidden "behind" a FS window havem_allowedOverFullscreen = true. Only when they are hidden 'behind' a FS window do they have this attr= false(this works for floating windows but is iffy for tiled - all but current FS window is always hidden anyway)FSMODE_MAX(andmode = 3along with it) as a user-settable option.Further Reading For Some Changes
FSMODE_MAX is no longer a user-facing mode, but is now a pure internal implementation detail. If a FS is requested by the client to be FSMODE_FULLSCREEN-ed while it is FSMODE_MAXIMIZED, it is considered in a special state (I called it FSMODE_MAX cuz the name already exists but it can be called something else.). It no longer has a special mode assigned to it.
This removes the confusion about what FSMODE_MAX is; and since it had no user-facing documentation about how it worked and why it existed, as well as the fact that it was really just FSMODE_FULLSCREEN as far as the user was concerned: it's moved to be a pure implementation detail now.
Requested values are now clamped to hi: FSMODE_FULLSCREEN so if users used
mode = 3, it'll silently fall back to using= 2.Fix a lot of bugs with scrolling FS behaviour:
Fixes for default handled FS
Misc improvements
expelof that window always act the same aspromotelayoutmsg dispatch. It makes more sense for the expelled target to go behind its prev. col, not before itNew Features
fullscreenHandlerto hyprctl andfullscreen_handlerattr to lua window class - as string.pinFullscreenedto hyprctl and lua window classFramework
Legacy - before the decision to refactor FS logic complately
Definitions
FS -> A window that may be Either:
FSMODE_FULLSCREENorFSMODE_MAXIMIZEDfullscreen window -> A window that
FSMODE_FULLSCREENmaximised window -> A window that is
FSMODE_MAXIMIZEDcovering FS/fullscreen/maximised window -> A window that is both FS, and is considered by the layout as the "currently in complete view fullscreen window".
--> The default and scrolling's handling of these windows are the same: If a window completely covers the whole monitor (fullscreen) or the whole work area (maximise), but different layouts may define this in different ways.
Maximize <-> Maximise -- Although we all know which one is the correct way of saying it π
FS Windows
Expose the following:
internal/client fullscreen modes: the fullscreen mode of the window.
m_target of the window has a
bool m_layoutManagedFullscreenflag.trueif window is layout managed,falseotherwise. This is used outside the FS related functions to differentiate between default and layout handled fullscreens.fullscreen handler enum.
m_layoutManagedFullscreenthen, and need to carve out scrolling handled FS windows as the sole exception.isFullscreen()method.Workspace
Have 2 fullscreen related attributes/methods
m_hasFullscreenWindow- This is true if there is a covering FS window in the workspacegetFullscreenWindow()- Returns the covering FS window of the workspace.Monitor
inFullscreenMode()- returnstrueif there's a covering FS window whose internal mode isFSMODE_FULLSCREEN(i.e. there's a fullscreen window)getFullscreenWindow()- calls workspace method of the same name; same return val.What FS behaviour a layout may own
A layout may own:
requestFullscreen())requestFullscreen()andlayoutFullscreenTarget())setNoMembersAboveFullscreen())layoutFullscreenTarget())A layout must override both
requestFullscreen()andlayoutFullscreenTarget()if it wished to own fullscreen behaviour, but may choose to not overridesetNoMembersAboveFullscreen()if it doesn't need window hiding behaviour different than the default.Needless to say, layouts can define whatever helper functions they need internally to handle the above. All of that is isolated to the layout's own source/header files and won't be used (or ideally available) outside of it.
Layouts handle each of these with minimal mixing of default handled fullscreen related code. As it is, some code related to default handled FS windows is inevitable as floating windows are always default handled; and in a future PR I'll make it possible to have a default handled tiled FS window in workspaces that have layouts that own FS semantics.
Default Handled FS
All layouts that don't define their own FS behaviour will use the default handled FS behaviour.
In a future PR, i'll add the ability to choose if the user wants to use default or layout FS behaviour in workspaces whose layout does define custom FS behaviour.
Note for default handled FS with master and monocle layouts
Both of these set a window's size and pos in recalculate() calls. therefore, there is code in both their recalculate() calls to correctly set or skip re-setting window pos-size if that window is fullscreen.
Layout handled FS
layoutFullscreenTarget()must return the target that is FS and is covering. Even if there is a covering floating FS window ontop, it must still return the covering FS window.isFullscreen()ofCWindowto judge if a window is fullscreen if that window is layout handled.requestFullscreen()defines how to FS/un-FS a window when the corresponding dispatch or internal call to set window's internal FS state is fired.setNoMembersAboveFullscreen()can be optionally overridden if a layout needs custom window hiding logic (e.g. floating windows when there's an underlying covering layout managed tiled FS window in scrolling layout).recalculate()- scrolling uses this to keep the shapes and sizes of non-covering (or focused) FS windows. I reckon other layouts that may own FS semantics in the future will also almost always make use of this.Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.)
Complete refactor of FS and some related things. Please read the description for the full list of changes and what they imply.
Known Bugs
f[0/1/2]MR Related Bug Tracking:
on_focus_under_fullscreen = 0-> maximise master, open a new tiled window. broken.TODO
Misc:
Details
- [ ] When moving windows around workspaces, windows should be properly unFSed before move and re-FSed after move. This should be the current behaviour -> make sure that it is reliableReplace all bitmap compare operators with == / != (????)
Don't forget null checks where appropriate
Test legacy dispatchers
Check that the viewport doesn't move when default FSed on scrolling
Additional virtual layouts may implement:
syncFullscreen()- if necessary. may not need thisGo over the framework part and properly document the current layout fullscreen logic
Clear up includes and forward decelerations
Refactor the Tiled (no need iirc), Master, monocle recalculate to better handle not
updatePos()- ing a window that's fullscreened.Clear comments made during PR.
Wiki MR TODO