diff --git a/src/input/mod.rs b/src/input/mod.rs index 803f5ef4..88b96afb 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -28,7 +28,7 @@ use smithay::{ }, output::Output, reexports::wayland_server::DisplayHandle, - utils::{Logical, Point, Rectangle, SERIAL_COUNTER}, + utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER}, wayland::{ keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat, seat::WaylandFocus, shell::wlr_layer::Layer as WlrLayer, @@ -266,7 +266,7 @@ impl State { ) .flatten() { - self.handle_action(action, seat) + self.handle_action(action, seat, serial, time) } break; } @@ -527,7 +527,7 @@ impl State { } } - fn handle_action(&mut self, action: Action, seat: &Seat) { + fn handle_action(&mut self, action: Action, seat: &Seat, serial: Serial, time: u32) { match action { Action::Terminate => { self.common.should_stop = true; @@ -553,15 +553,10 @@ impl State { 0 => 9, x => x - 1, }; - if let Some(motion_event) = self + let _ = self .common .shell - .activate(¤t_output, workspace as usize) - { - if let Some(ptr) = seat.get_pointer() { - ptr.motion(self, None, &motion_event); - } - } + .activate(¤t_output, workspace as usize); } Action::NextWorkspace => { let current_output = seat.active_output(); @@ -572,11 +567,7 @@ impl State { .active_num(¤t_output) .saturating_add(1); // TODO: Possibly move to next output, if idx to large - if let Some(motion_event) = self.common.shell.activate(¤t_output, workspace) { - if let Some(ptr) = seat.get_pointer() { - ptr.motion(self, None, &motion_event); - } - } + let _ = self.common.shell.activate(¤t_output, workspace); } Action::PreviousWorkspace => { let current_output = seat.active_output(); @@ -587,11 +578,7 @@ impl State { .active_num(¤t_output) .saturating_sub(1); // TODO: Possibly move to prev output, if idx < 0 - if let Some(motion_event) = self.common.shell.activate(¤t_output, workspace) { - if let Some(ptr) = seat.get_pointer() { - ptr.motion(self, None, &motion_event); - } - } + let _ = self.common.shell.activate(¤t_output, workspace); } Action::LastWorkspace => { let current_output = seat.active_output(); @@ -601,11 +588,7 @@ impl State { .workspaces .len(¤t_output) .saturating_sub(1); - if let Some(motion_event) = self.common.shell.activate(¤t_output, workspace) { - if let Some(ptr) = seat.get_pointer() { - ptr.motion(self, None, &motion_event); - } - } + let _ = self.common.shell.activate(¤t_output, workspace); } Action::MoveToWorkspace(key_num) => { let current_output = seat.active_output(); @@ -680,9 +663,18 @@ impl State { .cloned() { let idx = self.common.shell.workspaces.active_num(&next_output); - if let Some(motion_event) = self.common.shell.activate(&next_output, idx) { + if let Some(new_pos) = self.common.shell.activate(&next_output, idx) { + seat.set_active_output(&next_output); if let Some(ptr) = seat.get_pointer() { - ptr.motion(self, None, &motion_event); + ptr.motion( + self, + None, + &MotionEvent { + location: new_pos.to_f64(), + serial, + time, + }, + ); } } } @@ -701,9 +693,19 @@ impl State { .cloned() { let idx = self.common.shell.workspaces.active_num(&prev_output); - if let Some(motion_event) = self.common.shell.activate(&prev_output, idx) { + seat.set_active_output(&prev_output); + if let Some(new_pos) = self.common.shell.activate(&prev_output, idx) { + seat.set_active_output(&prev_output); if let Some(ptr) = seat.get_pointer() { - ptr.motion(self, None, &motion_event); + ptr.motion( + self, + None, + &MotionEvent { + location: new_pos.to_f64(), + serial, + time, + }, + ); } } } @@ -720,7 +722,24 @@ impl State { .next() .cloned() { - Shell::move_current_window(self, seat, ¤t_output, (&next_output, None)); + if let Some(new_pos) = Shell::move_current_window( + self, + seat, + ¤t_output, + (&next_output, None), + ) { + if let Some(ptr) = seat.get_pointer() { + ptr.motion( + self, + None, + &MotionEvent { + location: new_pos.to_f64(), + serial, + time, + }, + ); + } + } } } Action::MoveToPreviousOutput => { @@ -736,7 +755,24 @@ impl State { .next() .cloned() { - Shell::move_current_window(self, seat, ¤t_output, (&prev_output, None)); + if let Some(new_pos) = Shell::move_current_window( + self, + seat, + ¤t_output, + (&prev_output, None), + ) { + if let Some(ptr) = seat.get_pointer() { + ptr.motion( + self, + None, + &MotionEvent { + location: new_pos.to_f64(), + serial, + time, + }, + ); + } + } } } Action::Focus(focus) => { @@ -751,13 +787,17 @@ impl State { // TODO: Handle Workspace orientation match focus { FocusDirection::Left => { - self.handle_action(Action::PreviousWorkspace, seat) + self.handle_action(Action::PreviousWorkspace, seat, serial, time) } FocusDirection::Right => { - self.handle_action(Action::NextWorkspace, seat) + self.handle_action(Action::NextWorkspace, seat, serial, time) + } + FocusDirection::Up => { + self.handle_action(Action::PreviousOutput, seat, serial, time) + } + FocusDirection::Down => { + self.handle_action(Action::NextOutput, seat, serial, time) } - FocusDirection::Up => self.handle_action(Action::PreviousOutput, seat), - FocusDirection::Down => self.handle_action(Action::NextOutput, seat), _ => {} } } @@ -778,11 +818,17 @@ impl State { // TODO: Being able to move Groups (move_further should be KeyboardFocusTarget instead) match direction { Direction::Left => { - self.handle_action(Action::MoveToPreviousWorkspace, seat) + self.handle_action(Action::MoveToPreviousWorkspace, seat, serial, time) + } + Direction::Right => { + self.handle_action(Action::MoveToNextWorkspace, seat, serial, time) + } + Direction::Up => { + self.handle_action(Action::MoveToPreviousOutput, seat, serial, time) + } + Direction::Down => { + self.handle_action(Action::MoveToNextOutput, seat, serial, time) } - Direction::Right => self.handle_action(Action::MoveToNextWorkspace, seat), - Direction::Up => self.handle_action(Action::MoveToPreviousOutput, seat), - Direction::Down => self.handle_action(Action::MoveToNextOutput, seat), } } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 53d9b4b4..21cd8e6a 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState; use smithay::{ desktop::{layer_map_for_output, LayerSurface, PopupManager, Window, WindowSurfaceType}, - input::{pointer::MotionEvent, Seat}, + input::Seat, output::Output, reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle}, utils::{Logical, Point, Rectangle}, @@ -733,7 +733,7 @@ impl Shell { self.refresh(); // get rid of empty workspaces and enforce potential maximum } - pub fn activate(&mut self, output: &Output, idx: usize) -> Option { + pub fn activate(&mut self, output: &Output, idx: usize) -> Option> { match &mut self.workspaces { WorkspaceMode::OutputBound(sets, _) => { if let Some(set) = sets.get_mut(output) { @@ -745,7 +745,8 @@ impl Shell { } } - None + let output_geo = output.geometry(); + Some(output_geo.loc + Point::from((output_geo.size.w / 2, output_geo.size.h / 2))) } pub fn active_space(&self, output: &Output) -> &Workspace { @@ -1001,21 +1002,21 @@ impl Shell { seat: &Seat, from_output: &Output, to: (&Output, Option), - ) { + ) -> Option> { let (to_output, to_idx) = to; let to_idx = to_idx.unwrap_or(state.common.shell.workspaces.active_num(to_output)); if from_output == to_output && to_idx == state.common.shell.workspaces.active_num(from_output) { - return; + return None; } let from_workspace = state.common.shell.workspaces.active_mut(from_output); let maybe_window = from_workspace.focus_stack.get(seat).last().cloned(); - let Some(mapped) = maybe_window else { return; }; - let Some(window_state) = from_workspace.unmap(&mapped) else { return; }; + let Some(mapped) = maybe_window else { return None; }; + let Some(window_state) = from_workspace.unmap(&mapped) else { return None; }; for (toplevel, _) in mapped.windows() { state @@ -1030,6 +1031,9 @@ impl Shell { state.common.shell.update_reactive_popups(&mapped); } + seat.set_active_output(&to_output); + let new_pos = state.common.shell.activate(to_output, to_idx); + let to_workspace = state .common .shell @@ -1051,7 +1055,6 @@ impl Shell { .toplevel_info_state .toplevel_enter_workspace(&toplevel, &to_workspace.handle); } - for mapped in to_workspace .mapped() .cloned() @@ -1061,8 +1064,8 @@ impl Shell { state.common.shell.update_reactive_popups(&mapped); } - state.common.shell.activate(to_output, to_idx); Common::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None); + new_pos } pub fn update_reactive_popups(&self, mapped: &CosmicMapped) {