actions: Fix focus on Output-actions
This commit is contained in:
parent
932c204de4
commit
5006eae60b
3 changed files with 186 additions and 154 deletions
|
|
@ -3,8 +3,8 @@
|
|||
use crate::{
|
||||
config::{Action, PrivateAction},
|
||||
shell::{
|
||||
layout::tiling::SwapWindowGrab, FocusResult, InvalidWorkspaceIndex, MoveResult, SeatExt,
|
||||
Trigger, WorkspaceDelta,
|
||||
focus::target::KeyboardFocusTarget, layout::tiling::SwapWindowGrab, FocusResult,
|
||||
InvalidWorkspaceIndex, MoveResult, SeatExt, Trigger, WorkspaceDelta,
|
||||
},
|
||||
utils::prelude::*,
|
||||
wayland::{
|
||||
|
|
@ -402,11 +402,30 @@ impl State {
|
|||
WorkspaceDelta::new_shortcut(),
|
||||
&mut self.common.workspace_state.update(),
|
||||
);
|
||||
match res {
|
||||
Ok(Some(new_pos)) => {
|
||||
std::mem::drop(shell);
|
||||
seat.set_active_output(&next_output);
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
seat.set_active_output(&next_output);
|
||||
|
||||
if let Ok(Some(new_pos)) = res {
|
||||
let new_target = shell
|
||||
.workspaces
|
||||
.active(&next_output)
|
||||
.1
|
||||
.focus_stack
|
||||
.get(&seat)
|
||||
.last()
|
||||
.cloned()
|
||||
.map(KeyboardFocusTarget::from);
|
||||
std::mem::drop(shell);
|
||||
|
||||
let move_cursor = if let Some(under) = new_target {
|
||||
let update_cursor = self.common.config.cosmic_conf.focus_follows_cursor;
|
||||
Shell::set_focus(self, Some(&under), seat, None, update_cursor);
|
||||
!update_cursor
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
if move_cursor {
|
||||
ptr.motion(
|
||||
self,
|
||||
None,
|
||||
|
|
@ -416,13 +435,9 @@ impl State {
|
|||
time,
|
||||
},
|
||||
);
|
||||
ptr.frame(self);
|
||||
}
|
||||
ptr.frame(self);
|
||||
}
|
||||
Ok(None) => {
|
||||
seat.set_active_output(&next_output);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else if propagate {
|
||||
std::mem::drop(shell);
|
||||
|
|
@ -474,11 +489,30 @@ impl State {
|
|||
WorkspaceDelta::new_shortcut(),
|
||||
&mut self.common.workspace_state.update(),
|
||||
);
|
||||
match res {
|
||||
Ok(Some(new_pos)) => {
|
||||
std::mem::drop(shell);
|
||||
seat.set_active_output(&next_output);
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
seat.set_active_output(&next_output);
|
||||
|
||||
if let Ok(Some(new_pos)) = res {
|
||||
let new_target = shell
|
||||
.workspaces
|
||||
.active(&next_output)
|
||||
.1
|
||||
.focus_stack
|
||||
.get(&seat)
|
||||
.last()
|
||||
.cloned()
|
||||
.map(KeyboardFocusTarget::from);
|
||||
std::mem::drop(shell);
|
||||
|
||||
let move_cursor = if let Some(under) = new_target {
|
||||
let update_cursor = self.common.config.cosmic_conf.focus_follows_cursor;
|
||||
Shell::set_focus(self, Some(&under), seat, None, update_cursor);
|
||||
!update_cursor
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
if move_cursor {
|
||||
ptr.motion(
|
||||
self,
|
||||
None,
|
||||
|
|
@ -488,13 +522,9 @@ impl State {
|
|||
time,
|
||||
},
|
||||
);
|
||||
ptr.frame(self);
|
||||
}
|
||||
ptr.frame(self);
|
||||
}
|
||||
Ok(None) => {
|
||||
seat.set_active_output(&next_output);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -518,11 +548,30 @@ impl State {
|
|||
WorkspaceDelta::new_shortcut(),
|
||||
&mut self.common.workspace_state.update(),
|
||||
);
|
||||
match res {
|
||||
Ok(Some(new_pos)) => {
|
||||
std::mem::drop(shell);
|
||||
seat.set_active_output(&prev_output);
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
seat.set_active_output(&prev_output);
|
||||
|
||||
if let Ok(Some(new_pos)) = res {
|
||||
let new_target = shell
|
||||
.workspaces
|
||||
.active(&prev_output)
|
||||
.1
|
||||
.focus_stack
|
||||
.get(&seat)
|
||||
.last()
|
||||
.cloned()
|
||||
.map(KeyboardFocusTarget::from);
|
||||
std::mem::drop(shell);
|
||||
|
||||
let move_cursor = if let Some(under) = new_target {
|
||||
let update_cursor = self.common.config.cosmic_conf.focus_follows_cursor;
|
||||
Shell::set_focus(self, Some(&under), seat, None, update_cursor);
|
||||
!update_cursor
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
if move_cursor {
|
||||
ptr.motion(
|
||||
self,
|
||||
None,
|
||||
|
|
@ -532,13 +581,9 @@ impl State {
|
|||
time,
|
||||
},
|
||||
);
|
||||
ptr.frame(self);
|
||||
}
|
||||
ptr.frame(self);
|
||||
}
|
||||
Ok(None) => {
|
||||
seat.set_active_output(&prev_output);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
218
src/input/mod.rs
218
src/input/mod.rs
|
|
@ -603,9 +603,9 @@ impl State {
|
|||
//If the pointer isn't grabbed, we should check if the focused element should be updated
|
||||
} else if self.common.config.cosmic_conf.focus_follows_cursor {
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
let (old_keyboard_target, _) =
|
||||
let old_keyboard_target =
|
||||
shell.keyboard_target_from_position(original_position, &seat);
|
||||
let (new_keyboard_target, _) =
|
||||
let new_keyboard_target =
|
||||
shell.keyboard_target_from_position(position, &seat);
|
||||
|
||||
if old_keyboard_target != new_keyboard_target
|
||||
|
|
@ -904,123 +904,115 @@ impl State {
|
|||
let global_position =
|
||||
seat.get_pointer().unwrap().current_location().as_global();
|
||||
let shell = self.common.shell.write().unwrap();
|
||||
let (under, trigger_move) =
|
||||
shell.keyboard_target_from_position(global_position, &seat);
|
||||
if trigger_move {
|
||||
// Don't check override redirect windows, because we don't set keyboard focus to them explicitly.
|
||||
// These cases are handled by the XwaylandKeyboardGrab.
|
||||
if let Some(target) = shell.element_under(global_position, &output) {
|
||||
if seat.get_keyboard().unwrap().modifier_state().logo {
|
||||
if let Some(surface) = target.toplevel().map(Cow::into_owned) {
|
||||
let seat_clone = seat.clone();
|
||||
let mouse_button = PointerButtonEvent::button(&event);
|
||||
let under = shell.keyboard_target_from_position(global_position, &seat);
|
||||
// Don't check override redirect windows, because we don't set keyboard focus to them explicitly.
|
||||
// These cases are handled by the XwaylandKeyboardGrab.
|
||||
if let Some(target) = shell.element_under(global_position, &output) {
|
||||
if seat.get_keyboard().unwrap().modifier_state().logo {
|
||||
if let Some(surface) = target.toplevel().map(Cow::into_owned) {
|
||||
let seat_clone = seat.clone();
|
||||
let mouse_button = PointerButtonEvent::button(&event);
|
||||
|
||||
let mut supress_button = || {
|
||||
// If the logo is held then the pointer event is
|
||||
// aimed at the compositor and shouldn't be passed
|
||||
// to the application.
|
||||
pass_event = false;
|
||||
seat.supressed_buttons().add(button);
|
||||
};
|
||||
let mut supress_button = || {
|
||||
// If the logo is held then the pointer event is
|
||||
// aimed at the compositor and shouldn't be passed
|
||||
// to the application.
|
||||
pass_event = false;
|
||||
seat.supressed_buttons().add(button);
|
||||
};
|
||||
|
||||
fn dispatch_grab<G: PointerGrab<State> + 'static>(
|
||||
grab: Option<(G, smithay::input::pointer::Focus)>,
|
||||
seat: Seat<State>,
|
||||
serial: Serial,
|
||||
state: &mut State,
|
||||
) {
|
||||
if let Some((target, focus)) = grab {
|
||||
seat.modifiers_shortcut_queue().clear();
|
||||
fn dispatch_grab<G: PointerGrab<State> + 'static>(
|
||||
grab: Option<(G, smithay::input::pointer::Focus)>,
|
||||
seat: Seat<State>,
|
||||
serial: Serial,
|
||||
state: &mut State,
|
||||
) {
|
||||
if let Some((target, focus)) = grab {
|
||||
seat.modifiers_shortcut_queue().clear();
|
||||
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(state, target, serial, focus);
|
||||
}
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(state, target, serial, focus);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mouse_button) = mouse_button {
|
||||
match mouse_button {
|
||||
smithay::backend::input::MouseButton::Left => {
|
||||
supress_button();
|
||||
self.common.event_loop_handle.insert_idle(
|
||||
move |state| {
|
||||
let mut shell =
|
||||
state.common.shell.write().unwrap();
|
||||
let res = shell.move_request(
|
||||
&surface,
|
||||
&seat_clone,
|
||||
serial,
|
||||
ReleaseMode::NoMouseButtons,
|
||||
false,
|
||||
&state.common.config,
|
||||
&state.common.event_loop_handle,
|
||||
&state.common.xdg_activation_state,
|
||||
false,
|
||||
);
|
||||
drop(shell);
|
||||
dispatch_grab(
|
||||
res, seat_clone, serial, state,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
smithay::backend::input::MouseButton::Right => {
|
||||
supress_button();
|
||||
self.common.event_loop_handle.insert_idle(
|
||||
move |state| {
|
||||
let mut shell =
|
||||
state.common.shell.write().unwrap();
|
||||
let Some(target_elem) =
|
||||
shell.element_for_surface(&surface)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(geom) = shell
|
||||
.space_for(target_elem)
|
||||
.and_then(|f| {
|
||||
f.element_geometry(target_elem)
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let geom = geom.to_f64();
|
||||
let center =
|
||||
geom.loc + geom.size.downscale(2.0);
|
||||
let offset = center.to_global(&output)
|
||||
- global_position;
|
||||
let edge = match (
|
||||
offset.x > 0.0,
|
||||
offset.y > 0.0,
|
||||
) {
|
||||
(true, true) => {
|
||||
ResizeEdge::TOP_LEFT
|
||||
}
|
||||
(false, true) => {
|
||||
ResizeEdge::TOP_RIGHT
|
||||
}
|
||||
(true, false) => {
|
||||
ResizeEdge::BOTTOM_LEFT
|
||||
}
|
||||
(false, false) => {
|
||||
ResizeEdge::BOTTOM_RIGHT
|
||||
}
|
||||
};
|
||||
let res = shell.resize_request(
|
||||
&surface,
|
||||
&seat_clone,
|
||||
serial,
|
||||
edge,
|
||||
false,
|
||||
);
|
||||
drop(shell);
|
||||
dispatch_grab(
|
||||
res, seat_clone, serial, state,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
if let Some(mouse_button) = mouse_button {
|
||||
match mouse_button {
|
||||
smithay::backend::input::MouseButton::Left => {
|
||||
supress_button();
|
||||
self.common.event_loop_handle.insert_idle(
|
||||
move |state| {
|
||||
let mut shell =
|
||||
state.common.shell.write().unwrap();
|
||||
let res = shell.move_request(
|
||||
&surface,
|
||||
&seat_clone,
|
||||
serial,
|
||||
ReleaseMode::NoMouseButtons,
|
||||
false,
|
||||
&state.common.config,
|
||||
&state.common.event_loop_handle,
|
||||
&state.common.xdg_activation_state,
|
||||
false,
|
||||
);
|
||||
drop(shell);
|
||||
dispatch_grab(
|
||||
res, seat_clone, serial, state,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
smithay::backend::input::MouseButton::Right => {
|
||||
supress_button();
|
||||
self.common.event_loop_handle.insert_idle(
|
||||
move |state| {
|
||||
let mut shell =
|
||||
state.common.shell.write().unwrap();
|
||||
let Some(target_elem) =
|
||||
shell.element_for_surface(&surface)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(geom) =
|
||||
shell.space_for(target_elem).and_then(
|
||||
|f| f.element_geometry(target_elem),
|
||||
)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let geom = geom.to_f64();
|
||||
let center =
|
||||
geom.loc + geom.size.downscale(2.0);
|
||||
let offset = center.to_global(&output)
|
||||
- global_position;
|
||||
let edge = match (
|
||||
offset.x > 0.0,
|
||||
offset.y > 0.0,
|
||||
) {
|
||||
(true, true) => ResizeEdge::TOP_LEFT,
|
||||
(false, true) => ResizeEdge::TOP_RIGHT,
|
||||
(true, false) => {
|
||||
ResizeEdge::BOTTOM_LEFT
|
||||
}
|
||||
(false, false) => {
|
||||
ResizeEdge::BOTTOM_RIGHT
|
||||
}
|
||||
};
|
||||
let res = shell.resize_request(
|
||||
&surface,
|
||||
&seat_clone,
|
||||
serial,
|
||||
edge,
|
||||
false,
|
||||
);
|
||||
drop(shell);
|
||||
dispatch_grab(
|
||||
res, seat_clone, serial, state,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1424,10 +1424,8 @@ impl Shell {
|
|||
&self,
|
||||
global_position: Point<f64, Global>,
|
||||
seat: &Seat<State>,
|
||||
) -> (Option<KeyboardFocusTarget>, bool) {
|
||||
) -> Option<KeyboardFocusTarget> {
|
||||
let output = seat.active_output();
|
||||
// if not done and super key pressed
|
||||
let mut grab_conditions_met = false;
|
||||
let relative_pos = global_position.to_local(&output);
|
||||
|
||||
let mut under: Option<KeyboardFocusTarget> = None;
|
||||
|
|
@ -1484,11 +1482,7 @@ impl Shell {
|
|||
// Don't check override redirect windows, because we don't set keyboard focus to them explicitly.
|
||||
// These cases are handled by the XwaylandKeyboardGrab.
|
||||
if let Some(target) = self.element_under(global_position, &output) {
|
||||
if !seat.get_keyboard().unwrap().modifier_state().logo {
|
||||
under = Some(target);
|
||||
} else {
|
||||
grab_conditions_met = true;
|
||||
}
|
||||
under = Some(target);
|
||||
} else {
|
||||
let layers = layer_map_for_output(&output);
|
||||
if let Some(layer) = layers
|
||||
|
|
@ -1512,7 +1506,8 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
}
|
||||
(under, grab_conditions_met)
|
||||
|
||||
under
|
||||
}
|
||||
|
||||
/// Coerce a keyboard focus target into a CosmicMapped element. This is useful when performing window specific
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue