mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-25 09:59:21 +01:00
Make focus tag-specific
This commit is contained in:
parent
03d57e4b5d
commit
0f42e403ae
7 changed files with 63 additions and 60 deletions
|
@ -224,6 +224,7 @@ end
|
|||
---Get the currently focused window.
|
||||
---@return Window|nil
|
||||
function window_module.get_focused()
|
||||
-- TODO: get focused on output
|
||||
local windows = window_module.get_all()
|
||||
|
||||
for _, w in pairs(windows) do
|
||||
|
@ -238,8 +239,7 @@ end
|
|||
---Get all windows.
|
||||
---@return Window[]
|
||||
function window_module.get_all()
|
||||
local window_ids =
|
||||
Request("GetWindows").RequestResponse.response.Windows.window_ids
|
||||
local window_ids = Request("GetWindows").RequestResponse.response.Windows.window_ids
|
||||
|
||||
---@type Window[]
|
||||
local windows = {}
|
||||
|
@ -513,8 +513,7 @@ function window_module.fullscreen(win)
|
|||
window_id = win:id(),
|
||||
},
|
||||
})
|
||||
local fom =
|
||||
response.RequestResponse.response.WindowProps.fullscreen_or_maximized
|
||||
local fom = response.RequestResponse.response.WindowProps.fullscreen_or_maximized
|
||||
return fom == "Fullscreen"
|
||||
end
|
||||
|
||||
|
@ -528,8 +527,7 @@ function window_module.maximized(win)
|
|||
window_id = win:id(),
|
||||
},
|
||||
})
|
||||
local fom =
|
||||
response.RequestResponse.response.WindowProps.fullscreen_or_maximized
|
||||
local fom = response.RequestResponse.response.WindowProps.fullscreen_or_maximized
|
||||
return fom == "Maximized"
|
||||
end
|
||||
|
||||
|
|
40
src/focus.rs
40
src/focus.rs
|
@ -13,7 +13,10 @@ use smithay::{
|
|||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
|
||||
use crate::{state::State, window::WindowElement};
|
||||
use crate::{
|
||||
state::{State, WithState},
|
||||
window::WindowElement,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FocusState {
|
||||
|
@ -21,23 +24,30 @@ pub struct FocusState {
|
|||
pub focused_output: Option<Output>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
/// Get the currently focused window on `output`, if any.
|
||||
pub fn current_focus(&mut self, output: &Output) -> Option<WindowElement> {
|
||||
self.focus_state.focus_stack.retain(|win| win.alive());
|
||||
|
||||
let mut windows = self.focus_state.focus_stack.iter().rev().filter(|win| {
|
||||
let win_tags = win.with_state(|state| state.tags.clone());
|
||||
let output_tags =
|
||||
output.with_state(|state| state.focused_tags().cloned().collect::<Vec<_>>());
|
||||
|
||||
win_tags
|
||||
.iter()
|
||||
.any(|win_tag| output_tags.iter().any(|op_tag| win_tag == op_tag))
|
||||
});
|
||||
|
||||
windows.next().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl FocusState {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
// TODO: how does this work with unmapped windows?
|
||||
/// Get the currently focused window. If there is none, the previous focus is returned.
|
||||
pub fn current_focus(&mut self) -> Option<WindowElement> {
|
||||
while let Some(window) = self.focus_stack.last() {
|
||||
if window.alive() {
|
||||
return Some(window.clone());
|
||||
}
|
||||
self.focus_stack.pop();
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Set the currently focused window.
|
||||
pub fn set_focus(&mut self, window: WindowElement) {
|
||||
self.focus_stack.retain(|win| win != &window);
|
||||
|
@ -46,8 +56,8 @@ impl FocusState {
|
|||
|
||||
/// Fix focus layering for all windows in the `focus_stack`.
|
||||
///
|
||||
/// This will call `space.map_element` on all windows from front
|
||||
/// to back to correct their z locations.
|
||||
/// This will call `space.raise_element` on all windows from back
|
||||
/// to front to correct their z locations.
|
||||
pub fn fix_up_focus(&self, space: &mut Space<WindowElement>) {
|
||||
for win in self.focus_stack.iter() {
|
||||
space.raise_element(win, false);
|
||||
|
|
|
@ -328,10 +328,13 @@ impl SeatHandler for State {
|
|||
}
|
||||
|
||||
fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Self::KeyboardFocus>) {
|
||||
if let Some(focus) =
|
||||
if let Some(win) =
|
||||
focused.and_then(|focused| self.window_for_surface(&focused.wl_surface()?))
|
||||
{
|
||||
self.focus_state.set_focus(focus);
|
||||
if let WindowElement::Wayland(win) = &win {
|
||||
win.set_activated(true);
|
||||
}
|
||||
self.focus_state.set_focus(win);
|
||||
}
|
||||
let focus_client = focused.and_then(|foc_target| {
|
||||
self.display_handle
|
||||
|
|
|
@ -121,16 +121,31 @@ impl XdgShellHandler for State {
|
|||
.wl_surface()
|
||||
.is_some_and(|surf| &surf != surface.wl_surface())
|
||||
});
|
||||
if let Some(focused_output) = self.focus_state.focused_output.as_ref().cloned() {
|
||||
self.update_windows(&focused_output);
|
||||
self.focus_state.focus_stack.retain(|window| {
|
||||
window
|
||||
.wl_surface()
|
||||
.is_some_and(|surf| &surf != surface.wl_surface())
|
||||
});
|
||||
|
||||
let Some(window) = self.window_for_surface(surface.wl_surface()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(output) = window.output(self) {
|
||||
self.update_windows(&output);
|
||||
let focus = self.current_focus(&output).map(FocusTarget::Window);
|
||||
if let Some(FocusTarget::Window(win)) = &focus {
|
||||
tracing::debug!("Focusing on prev win");
|
||||
self.space.raise_element(win, true);
|
||||
if let WindowElement::Wayland(win) = &win {
|
||||
win.toplevel().send_configure();
|
||||
}
|
||||
}
|
||||
self.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard")
|
||||
.set_focus(self, focus, SERIAL_COUNTER.next_serial());
|
||||
}
|
||||
|
||||
let focus = self.focus_state.current_focus().map(FocusTarget::Window);
|
||||
|
||||
self.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard")
|
||||
.set_focus(self, focus, SERIAL_COUNTER.next_serial());
|
||||
}
|
||||
|
||||
fn new_popup(&mut self, surface: PopupSurface, _positioner: PositionerState) {
|
||||
|
|
22
src/input.rs
22
src/input.rs
|
@ -268,16 +268,10 @@ impl State {
|
|||
let pointer = self.seat.get_pointer().expect("Seat has no pointer"); // FIXME: handle err
|
||||
let keyboard = self.seat.get_keyboard().expect("Seat has no keyboard"); // FIXME: handle err
|
||||
|
||||
// A serial is a number sent with a event that is sent back to the
|
||||
// server by the clients in further requests. This allows the server to
|
||||
// keep track of which event caused which requests. It is an AtomicU32
|
||||
// that increments when next_serial is called.
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
|
||||
// Returns which button on the pointer was used.
|
||||
let button = event.button_code();
|
||||
|
||||
// The state, either released or pressed.
|
||||
let button_state = event.state();
|
||||
|
||||
let pointer_loc = pointer.current_location();
|
||||
|
@ -390,21 +384,7 @@ impl State {
|
|||
});
|
||||
|
||||
if let FocusTarget::Window(window) = &focus {
|
||||
let focused_name = match &window {
|
||||
WindowElement::Wayland(win) => {
|
||||
compositor::with_states(win.toplevel().wl_surface(), |states| {
|
||||
let lock = states
|
||||
.data_map
|
||||
.get::<smithay::wayland::shell::xdg::XdgToplevelSurfaceData>()
|
||||
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
|
||||
.lock()
|
||||
.expect("failed to acquire lock");
|
||||
lock.app_id.clone().unwrap_or_default()
|
||||
})
|
||||
}
|
||||
WindowElement::X11(surf) => surf.class(),
|
||||
};
|
||||
tracing::debug!("setting keyboard focus to {focused_name}");
|
||||
tracing::debug!("setting keyboard focus to {:?}", window.class());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -166,7 +166,6 @@ impl State {
|
|||
// schedule on all idle
|
||||
self.schedule(
|
||||
move |_dt| {
|
||||
tracing::debug!("Waiting for all to be idle");
|
||||
let all_idle = pending_wins
|
||||
.iter()
|
||||
.filter(|(_, win)| win.alive())
|
||||
|
@ -178,8 +177,6 @@ impl State {
|
|||
.filter(|(_, win)| !win.with_state(|state| state.loc_request_state.is_idle()))
|
||||
.count();
|
||||
|
||||
tracing::debug!("{num_not_idle} not idle");
|
||||
|
||||
all_idle
|
||||
},
|
||||
move |dt| {
|
||||
|
|
|
@ -271,7 +271,8 @@ impl State {
|
|||
.api_state
|
||||
.stream
|
||||
.as_ref()
|
||||
.expect("Stream doesn't exist");
|
||||
.expect("Stream doesn't exist")
|
||||
.clone();
|
||||
let mut stream = stream.lock().expect("Couldn't lock stream");
|
||||
match request {
|
||||
Request::GetWindows => {
|
||||
|
@ -319,9 +320,8 @@ impl State {
|
|||
WindowElement::X11(surface) => (Some(surface.class()), Some(surface.title())),
|
||||
});
|
||||
let focused = window.as_ref().and_then(|win| {
|
||||
self.focus_state
|
||||
.current_focus() // TODO: actual focus
|
||||
.map(|foc_win| win == &foc_win)
|
||||
let output = win.output(self)?;
|
||||
self.current_focus(&output).map(|foc_win| win == &foc_win)
|
||||
});
|
||||
let floating = window
|
||||
.as_ref()
|
||||
|
|
Loading…
Reference in a new issue