-
-
Notifications
You must be signed in to change notification settings - Fork 25
Feature: window minimisation #420
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: main
Are you sure you want to change the base?
Changes from 18 commits
0c9832d
65062c4
3d7bad0
616767d
5786a8a
641ef7a
4d79958
c2fdf27
e768db2
2a7d4cf
e0b1e9a
a842d94
749d1c7
d863624
de4b69b
c19693e
0dd548a
6b2e760
7fc65dc
de32422
33acbf1
1b89758
7a6cc1d
8fc71b1
5a67b22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -151,6 +151,33 @@ async fn config() { | |
| .group("Window") | ||
| .description("Toggle maximized on the focused window"); | ||
|
|
||
| // `mod_key + n` makes minimized | ||
| input::keybind(mod_key, 'n') | ||
| .on_press(|| { | ||
| if let Some(window) = window::get_focused() { | ||
| window.set_minimized(true); | ||
| } | ||
| }) | ||
| .group("Window") | ||
| .description("Minimize the focused window"); | ||
|
|
||
| // `mon_key + shift + n` unminimises the "most recently focused" | ||
| // minimised window that is on the active tags in this current output. | ||
| input::keybind(mod_key | Mod::SHIFT, 'n') | ||
| .on_press(|| { | ||
| let Some(output) = output::get_focused() else { return }; | ||
| let Some(most_recently_minimised_active_window) = output | ||
| .keyboard_focus_stack_visible() | ||
| .filter(|w| w.minimized()) | ||
| .last() | ||
|
Comment on lines
+170
to
+172
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note on recent modification: The name of the API function "keyboard_focus_stack_visible" seems misleading now that minimised windows are a thing >.<
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm guess we can deprecate it and add a renamed function
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some sort of change seems to have made minimized windows not show up in it anyway (as they now lack a location), which makes more sense for the name anyway IMO (as they're not visible :p). But this also breaks the focus stack as a more general tool since it filters out windows by location down in the element check and minimization deletes that for some reason. Or at the very least the minimized windows don't get listed for their associated outputs and I think it's for that reason based on some testing >.<... |
||
| else { | ||
| return; | ||
| }; | ||
| most_recently_minimised_active_window.set_minimized(false); | ||
| }) | ||
| .group("Window") | ||
| .description("Unminimize the most recently focused window on the active tags"); | ||
|
|
||
| // Media keybinds ------------------------------------------------------ | ||
|
|
||
| input::keybind(Mod::empty(), Keysym::XF86_AudioRaiseVolume) | ||
|
|
@@ -462,7 +489,7 @@ async fn config() { | |
|
|
||
| // Enable sloppy focus | ||
| window::connect_signal(WindowSignal::PointerEnter(Box::new(|win| { | ||
| win.set_focused(true); | ||
| let _ = win.try_set_focused(true); | ||
| }))); | ||
|
|
||
| // Focus outputs when the pointer enters them | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,12 +19,12 @@ use pinnacle_api_defs::pinnacle::{ | |
| self, | ||
| v1::{ | ||
| GetAppIdRequest, GetFocusedRequest, GetForeignToplevelListIdentifierRequest, | ||
| GetLayoutModeRequest, GetLocRequest, GetSizeRequest, GetTagIdsRequest, GetTitleRequest, | ||
| GetWindowsInDirRequest, LowerRequest, MoveGrabRequest, MoveToOutputRequest, | ||
| MoveToTagRequest, RaiseRequest, ResizeGrabRequest, ResizeTileRequest, | ||
| SetDecorationModeRequest, SetFloatingRequest, SetFocusedRequest, SetFullscreenRequest, | ||
| SetGeometryRequest, SetMaximizedRequest, SetTagRequest, SetTagsRequest, | ||
| SetVrrDemandRequest, SwapRequest, | ||
| GetLayoutModeRequest, GetLocRequest, GetMinimizedRequest, GetSizeRequest, | ||
| GetTagIdsRequest, GetTitleRequest, GetWindowsInDirRequest, LowerRequest, | ||
| MoveGrabRequest, MoveToOutputRequest, MoveToTagRequest, RaiseRequest, | ||
| ResizeGrabRequest, ResizeTileRequest, SetDecorationModeRequest, SetFloatingRequest, | ||
| SetFullscreenRequest, SetGeometryRequest, SetMaximizedRequest, SetMinimizedRequest, | ||
| SetTagRequest, SetTagsRequest, SetVrrDemandRequest, SwapRequest, TrySetFocusedRequest, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
@@ -38,7 +38,7 @@ use crate::{ | |
| output::OutputHandle, | ||
| signal::{SignalHandle, WindowSignal}, | ||
| tag::TagHandle, | ||
| util::{Batch, Direction, Point, Size}, | ||
| util::{Batch, Direction, Point, ResultExt, Size}, | ||
| }; | ||
|
|
||
| /// Gets handles to all windows. | ||
|
|
@@ -235,6 +235,29 @@ impl VrrDemand { | |
| } | ||
| } | ||
|
|
||
| /// Error when trying to focus/unfocus a window. | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| pub enum TrySetFocusedError { | ||
| /// Window was minimized and could not be focused. | ||
| WindowMinimized, | ||
| } | ||
|
|
||
| impl TryFrom<pinnacle_api_defs::pinnacle::window::v1::TrySetFocusedResponse> | ||
| for TrySetFocusedError | ||
| { | ||
| type Error = (); | ||
|
|
||
| fn try_from( | ||
| value: pinnacle_api_defs::pinnacle::window::v1::TrySetFocusedResponse, | ||
| ) -> Result<Self, Self::Error> { | ||
| use pinnacle_api_defs::pinnacle::window::v1::try_set_focused_response::TrySetFocusedStatus; | ||
| match value.status() { | ||
| TrySetFocusedStatus::Success => Err(()), | ||
| TrySetFocusedStatus::WindowMinimized => Ok(Self::WindowMinimized), | ||
| } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just my 2c, but this feels weird (as does the whole swap_ok_err() extension method). Is there a reason not to implement
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it's just a gut-feeling, maybe don't act on it until Ottatop give an input :) If the issue is that rust don't like when we implements foreign traits on foreign types, it was solved on the server-side by having a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahhh... I probably should have done that instead of TryFrom, yes. There was a reason (when I had TrySetFocusedError as part of the protobuf generated rust files, I couldn't implement the trait due to orphan rules) but it shouldn't be an issue now ^.^
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, scratch that, it still doesn't work. I could try implementing Edit: this also doesn't work. Didn't think it would but just wanted to check. The problem is that both
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could also create a separate
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you tried, but the orphan rule shouldn't apply if the trait is local to the crate (i.e. if you copy https://github.com/pinnacle-comp/pinnacle/blob/main/snowcap/src/util/convert.rs to from server-side to the config api & use FromAPI instead of From)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. I was using the "default" |
||
|
|
||
| impl WindowHandle { | ||
| /// Sends a close request to this window. | ||
| /// | ||
|
|
@@ -365,6 +388,34 @@ impl WindowHandle { | |
| .unwrap(); | ||
| } | ||
|
|
||
| /// Sets this window to minimized or not. | ||
| pub fn set_minimized(&self, set: bool) { | ||
| let window_id = self.id; | ||
| Client::window() | ||
| .set_minimized(SetMinimizedRequest { | ||
| window_id, | ||
| set_or_toggle: match set { | ||
| true => SetOrToggle::Set, | ||
| false => SetOrToggle::Unset, | ||
| } | ||
| .into(), | ||
| }) | ||
| .block_on_tokio() | ||
| .unwrap(); | ||
| } | ||
|
|
||
| /// Toggles this window between minimized and not. | ||
| pub fn toggle_minimized(&self) { | ||
| let window_id = self.id; | ||
| Client::window() | ||
| .set_minimized(SetMinimizedRequest { | ||
| window_id, | ||
| set_or_toggle: SetOrToggle::Toggle.into(), | ||
| }) | ||
| .block_on_tokio() | ||
| .unwrap(); | ||
| } | ||
|
|
||
| /// Sets this window to floating or not. | ||
| /// | ||
| /// Floating windows will not be tiled and can be moved around and resized freely. | ||
|
|
@@ -398,10 +449,20 @@ impl WindowHandle { | |
| } | ||
|
|
||
| /// Focuses or unfocuses this window. | ||
| /// | ||
| /// Silently fails if trying to focus a minimized window. | ||
| #[deprecated = "use `WindowHandle::try_set_focused` instead"] | ||
| pub fn set_focused(&self, set: bool) { | ||
| let _ = self.try_set_focused(set); | ||
| } | ||
|
|
||
| /// Tries to focus or unfocus this window. | ||
| /// | ||
| /// Fails if the window is minimized. | ||
| pub fn try_set_focused(&self, set: bool) -> Result<(), TrySetFocusedError> { | ||
| let window_id = self.id; | ||
| Client::window() | ||
| .set_focused(SetFocusedRequest { | ||
| .try_set_focused(TrySetFocusedRequest { | ||
| window_id, | ||
| set_or_toggle: match set { | ||
| true => SetOrToggle::Set, | ||
|
|
@@ -410,19 +471,35 @@ impl WindowHandle { | |
| .into(), | ||
| }) | ||
| .block_on_tokio() | ||
| .unwrap(); | ||
| .expect("successful rpc communication is expected") | ||
| .into_inner() | ||
| .try_into() | ||
| .swap_ok_err() | ||
| } | ||
|
|
||
| /// Toggles this window between focused and unfocused. | ||
| /// | ||
| /// Silently fails if trying to focus a minimized window. | ||
| #[deprecated = "use `WindowHandle::try_toggle_focused` instead"] | ||
| pub fn toggle_focused(&self) { | ||
| let _ = self.try_toggle_focused(); | ||
| } | ||
|
|
||
| /// Tries to toggle this window between focused and unfocused. | ||
| /// | ||
| /// Fails if the window is minimized. | ||
| pub fn try_toggle_focused(&self) -> Result<(), TrySetFocusedError> { | ||
| let window_id = self.id; | ||
| Client::window() | ||
| .set_focused(SetFocusedRequest { | ||
| .try_set_focused(TrySetFocusedRequest { | ||
| window_id, | ||
| set_or_toggle: SetOrToggle::Toggle.into(), | ||
| }) | ||
| .block_on_tokio() | ||
| .unwrap(); | ||
| .expect("successful rpc communication is expected") | ||
| .into_inner() | ||
| .try_into() | ||
| .swap_ok_err() | ||
| } | ||
|
|
||
| /// Sets this window's decoration mode. | ||
|
|
@@ -807,6 +884,22 @@ impl WindowHandle { | |
| self.layout_mode_async().await == LayoutMode::Maximized | ||
| } | ||
|
|
||
| /// Gets whether or not this window is minimized | ||
| pub fn minimized(&self) -> bool { | ||
| self.minimized_async().block_on_tokio() | ||
| } | ||
|
|
||
| /// Async impl for [`Self::minimized`] | ||
| pub async fn minimized_async(&self) -> bool { | ||
| let window_id = self.id; | ||
| Client::window() | ||
| .get_minimized(GetMinimizedRequest { window_id }) | ||
| .await | ||
| .unwrap() | ||
| .into_inner() | ||
| .minimized | ||
| } | ||
|
|
||
| /// Gets handles to all tags on this window. | ||
| pub fn tags(&self) -> impl Iterator<Item = TagHandle> + use<> { | ||
| self.tags_async().block_on_tokio() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.