Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ impl State {
for seat in self.common.shell.read().seats.iter() {
let devices = seat.user_data().get::<Devices>().unwrap();
if devices.has_device(&WinitVirtualDevice) {
seat.set_active_output(&self.backend.winit().output);
seat.set_active_output(&self.backend.winit().output, false);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ impl State {
for seat in self.common.shell.read().seats.iter() {
let devices = seat.user_data().get::<Devices>().unwrap();
if devices.has_device(&device) {
seat.set_active_output(&output);
seat.set_active_output(&output, false);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/input/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ impl State {
WorkspaceDelta::new_shortcut(),
&mut workspace_guard,
);
seat.set_active_output(&next_output);
seat.set_active_output(&next_output, false);
res
};

Expand Down
2 changes: 1 addition & 1 deletion src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ impl State {
for session in cursor_sessions_for_output(&shell, &current_output) {
session.set_cursor_pos(None);
}
seat.set_active_output(&output);
seat.set_active_output(&output, false);
}

update_output_image_copy_cursor_position(
Expand Down
2 changes: 1 addition & 1 deletion src/shell/focus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ impl Common {
}
if !shell.outputs().any(|o| o == &active_output) {
if let Some(other) = shell.outputs().next() {
seat.set_active_output(other);
seat.set_active_output(other, true);
}
continue;
}
Expand Down
8 changes: 4 additions & 4 deletions src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ impl Workspaces {
if let Some(new_output) = new_output {
for seat in seats {
if &seat.active_output() == output {
seat.set_active_output(&new_output);
seat.set_active_output(&new_output, true);
}
if seat.focused_output().as_ref() == Some(output) {
seat.set_focused_output(None);
Expand Down Expand Up @@ -3144,7 +3144,7 @@ impl Shell {
node, focus_stack, ..
})) => {
let new_pos = if follow {
seat.set_active_output(to_output);
seat.set_active_output(to_output, false);
self.workspaces
.idx_for_handle(to_output, &to)
.and_then(|to_idx| {
Expand Down Expand Up @@ -3362,7 +3362,7 @@ impl Shell {

let new_pos = if follow {
if let Some(seat) = seat {
seat.set_active_output(&to_output);
seat.set_active_output(&to_output, false);
}
self.workspaces
.idx_for_handle(&to_output, to)
Expand Down Expand Up @@ -3473,7 +3473,7 @@ impl Shell {
}
let new_pos = if follow {
if let Some(seat) = seat {
seat.set_active_output(&to_output);
seat.set_active_output(&to_output, false);
}
self.workspaces
.idx_for_handle(&to_output, to)
Expand Down
66 changes: 63 additions & 3 deletions src/shell/seats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,31 @@ pub fn create_seat(
)
})
.expect("Failed to load xkb configuration files");
seat.add_pointer();

let pointer = seat.add_pointer();

// If possible, set the cursor's position to the center of the screen upon initialization
if let Some(position) = get_logical_center_of_output(output) {
pointer.set_location(position);
}

seat.add_touch();

seat
}

fn get_logical_center_of_output(output: &Output) -> Option<Point<f64, Logical>> {
output.current_mode().map(|mode| {
let output_position = output.current_location();
let scale = output.current_scale().fractional_scale();
let logical_size = mode.size.to_f64().to_logical(scale);
Point::new(
output_position.x as f64 + logical_size.w / 2.0,
output_position.y as f64 + logical_size.h / 2.0,
)
})
}

#[derive(Debug, Copy, Clone)]
pub struct CursorGeometry {
pub geometry: Rectangle<i32, Buffer>,
Expand All @@ -258,7 +277,7 @@ pub trait SeatExt {
self.focused_output()
.unwrap_or_else(|| self.active_output())
}
fn set_active_output(&self, output: &Output);
fn set_active_output(&self, output: &Output, move_cursor_to_center: bool);
fn set_focused_output(&self, output: Option<&Output>);
fn devices(&self) -> &Devices;
fn supressed_keys(&self) -> &SupressedKeys;
Expand All @@ -268,6 +287,12 @@ pub trait SeatExt {
fn pointer_constraint_hint(&self) -> Option<(WlSurface, Point<f64, Logical>)>;
fn set_pointer_constraint_hint(&self, hint: Option<(WlSurface, Point<f64, Logical>)>);

fn get_pointer_position_relative_to_active_output(&self) -> Option<Point<f64, Logical>>;
fn set_pointer_position_relative_to_active_output(
&self,
relative_position: Point<f64, Logical>,
);

fn cursor_geometry(
&self,
loc: impl Into<Point<f64, Buffer>>,
Expand Down Expand Up @@ -306,14 +331,23 @@ impl SeatExt for Seat<State> {
}
}

fn set_active_output(&self, output: &Output) {
fn set_active_output(&self, output: &Output, move_cursor_to_center: bool) {
*self
.user_data()
.get::<ActiveOutput>()
.unwrap()
.0
.lock()
.unwrap() = output.clone();

if move_cursor_to_center {
// Update the position of the cursor to the center
if let (Some(pointer), Some(position)) =
(self.get_pointer(), get_logical_center_of_output(output))
{
pointer.set_location(position);
}
}
}

fn set_focused_output(&self, output: Option<&Output>) {
Expand Down Expand Up @@ -369,6 +403,32 @@ impl SeatExt for Seat<State> {
*lock.0.lock().unwrap() = hint;
}

fn get_pointer_position_relative_to_active_output(&self) -> Option<Point<f64, Logical>> {
let output = self.active_output();

let pointer_position = self.get_pointer()?.current_location();
let output_position = output.current_location();

Some(Point::new(
pointer_position.x - output_position.x as f64,
pointer_position.y - output_position.y as f64,
))
}
fn set_pointer_position_relative_to_active_output(
&self,
relative_position: Point<f64, Logical>,
) {
let output = self.active_output();
let output_position = output.current_location();

if let Some(pointer) = self.get_pointer() {
pointer.set_location(Point::new(
relative_position.x + output_position.x as f64,
relative_position.y + output_position.y as f64,
));
}
}

fn cursor_geometry(
&self,
loc: impl Into<Point<f64, Buffer>>,
Expand Down
21 changes: 21 additions & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,20 @@ impl LockedBackend<'_> {
) -> Result<(), anyhow::Error> {
let all_outputs = self.all_outputs();

// Save the positions of the cursor relative to the output
let saved_cursor_positions = {
let guard = shell.read();
guard
.seats
.iter()
.filter_map(|seat| {
let rel_pos = seat.get_pointer_position_relative_to_active_output()?;
let active_output = seat.active_output();
Some((seat.clone(), active_output, rel_pos))
})
.collect::<Vec<_>>()
};

// update outputs, so that `OutputModeSource`s are correct
for output in &all_outputs {
// apply to Output
Expand Down Expand Up @@ -528,6 +542,13 @@ impl LockedBackend<'_> {
output.set_adaptive_sync(final_config.0.vrr);
}

// Restore cursor position relative to active output
for (seat, saved_output, rel_pos) in &saved_cursor_positions {
if &seat.active_output() == saved_output {
seat.set_pointer_position_relative_to_active_output(*rel_pos);
}
}

match self {
LockedBackend::Kms(state) => state.apply_config_for_outputs(
test_only,
Expand Down
2 changes: 1 addition & 1 deletion src/wayland/handlers/toplevel_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl ToplevelManagementHandler for State {
&& self.common.config.cosmic_conf.cursor_follows_focus
&& let Some(new_pos) = new_pos
{
seat.set_active_output(output);
seat.set_active_output(output, false);
if let Some(ptr) = seat.get_pointer() {
let serial = SERIAL_COUNTER.next_serial();
ptr.motion(
Expand Down