-
-
Notifications
You must be signed in to change notification settings - Fork 48
feat: add layout cycling widget and shortcut #345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v17.0
Are you sure you want to change the base?
Conversation
Oh wow, you made an amazing job! I'm about to review it |
export class LayoutSwitcherPopup { | ||
private _popup!: St.Widget; | ||
private _layoutList!: St.BoxLayout; | ||
private _layouts: Layout[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to not save a reference of the layouts outside of the global state. So instead of having this private field, you can always do GlobalState.get().layouts
. Now that I see this, I understand that the GlobalState could be better, ensuring it is the only one having the state and having the rights to manage it
private _getCurrentMonitorIndex(): number { | ||
const focusWindow = global.display.focus_window; | ||
if (focusWindow) return focusWindow.get_monitor(); | ||
|
||
return Main.layoutManager.primaryIndex; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is perfect!
import GlobalState from '@utils/globalState'; | ||
import Settings from '@settings/settings'; | ||
import { St, Clutter, GLib } from '@gi.ext'; | ||
import { Gtk } from '@gi.prefs'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the imports from @gi.prefs
are not allowed in the code driving the extension but only in the code driving the extension's preferences 😢
I put in @gi.prefs
everything that can be imported by extension's preferences only and in @gi.ext
everything that we are allowed to import in the extension code only. Unfortunately this is a requirement coming from GNOME, they will not publish any update that goes against this (source)
private _populateLayouts() { | ||
const buttonSize = { width: 142, height: 80 }; | ||
const hasGaps = Settings.get_inner_gaps(1).top > 0; | ||
const gapSize = hasGaps ? 2 : 0; | ||
|
||
this._layoutButtons = this._layouts.map((layout, ind) => { | ||
const container = new St.Widget({ | ||
style_class: 'layout-switcher-item', | ||
}); | ||
|
||
this._layoutList.add_child(container); | ||
|
||
const button = new LayoutButton( | ||
container, | ||
layout, | ||
gapSize, | ||
buttonSize.height, | ||
buttonSize.width, | ||
); | ||
|
||
if (ind === this._selectedIndex) button.set_checked(true); | ||
return button; | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is perfect!!
Settings.SETTING_CYCLE_LAYOUTS, | ||
); | ||
|
||
const switcher = new LayoutSwitcherPopup(keybindings); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it is possible to not construct the object every time, but instead, to construct only once and then hide/show when it is needed?
Thank you SO much for your contribution, it is invaluable! I just added comments about very important things, but the overall work is extremely solid, well done!
Yeah, don't worry. I can figure out witch CSS classes they use so we can use them as well. This will immediately enable us to support the GNOME theme the user has!
Let me check how GNOME does with their ALT+TAB, I think we can mimic that.
I believe here you picked the best approach! |
I see they have class AppSwitcherPopup which extends the class SwitcherPopup. SwitcherPopup basically has everything we need, from keybindings handling to positioning in the middle of the screen |
Hello! I made some progress on this, by following your contribution and how GNOME shell does the ALT+TAB one. Video.del.2025-05-31.17-12-14.webmI'm going to edit the pull request, so you can have those changes too. Few things:
|
Hmmmm I don't have experience with GitHub and I was not able to edit the PR. I pushed my changes in branch https://github.com/domferr/tilingshell/tree/joj0s/feat/layout-cycling |
Hey, first of all no worries, let's pick up from the branch you created. I tested it locally and functionality wise it seems to be working great so far! Just a minor issue where it takes a bit long to detect the release of the keybinding. Would you like me to check out anything in particular and work on that branch? |
Great!
I confirm that I also have that behaviour. I believe it comes from setting 0 as mask value here. GNOME shell provides the actual mask of the binding (source) by exposing the binding from the keybinding event. However, in my experimentations the |
You're right, it does come from the 0 mask value. And yeah, for some reason the const action = Main.wm.addKeybinding(
Settings.SETTING_CYCLE_LAYOUTS,
extensionSettings,
Meta.KeyBindingFlags.NONE,
Shell.ActionMode.NORMAL,
(display: Meta.Display, _, event: Clutter.Event) => {
const keyBinding = event as any;
const mask = keyBinding.get_mask();
this.emit('cycle-layouts', display, action, mask);
},
); I can only push changes to my own fork but feel free to try it out. That seems to solve the release check issue with most keybinding combinations, but again the same problems arise when using combinations with I am thinking of possibly overriding vfunc_key_release_event to manually detect super key modifiers in this case. |
Hey @joj0s that's a good catch! I confirm it fixes the issue to me as well, I pushed it in the branch. Can you share some more details about the other problem you are facing? |
Huh, nevermind, I had some issues yesterday where if I set up the cycling keybinding to be Re-tested it today, it works and I can't reproduce it anymore. If you also have no issues I'd say it's looking good |
Hello, sorry for the late reply, I believe this is looking great! I'll close the pull request and merge the branch with our work. Is it ok for you if I cite your github account in release notes? |
Happy to hear that!
Of course, go right ahead! |
This PR implements feature request #50 , adding a widget which allows users to switch between their defined layouts via keyboard shorcuts.
Possible discussion points:
<Super>
accelerator were quite iffy (Masking them using Gtk methods and detecting when the user released them) so I resorted to polling for pressed modifiers. If you think there is a better way of doing this feel free to edit this PR!Tested on Gnome 47 and Gnome 48 on Wayland