Skip to content
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

feat: Super + Right Click to open window context menu #1118

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
3 changes: 3 additions & 0 deletions cosmic-comp-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub struct CosmicCompConfig {
pub focus_follows_cursor_delay: u64,
/// Let X11 applications scale themselves
pub descale_xwayland: bool,
/// How far the pointer can travel before it's considered as moved
pub pointer_moved_epsilon: u32,
}

impl Default for CosmicCompConfig {
Expand Down Expand Up @@ -60,6 +62,7 @@ impl Default for CosmicCompConfig {
cursor_follows_focus: false,
focus_follows_cursor_delay: 250,
descale_xwayland: false,
pointer_moved_epsilon: 10,
}
}
}
Expand Down
232 changes: 186 additions & 46 deletions src/input/mod.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/shell/element/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ impl Program for CosmicStackInternal {
true,
&state.common.config,
&state.common.event_loop_handle,
true,
);

std::mem::drop(shell);
Expand Down Expand Up @@ -914,6 +915,7 @@ impl Program for CosmicStackInternal {
false,
&state.common.config,
&state.common.event_loop_handle,
true,
);

std::mem::drop(shell);
Expand Down
1 change: 1 addition & 0 deletions src/shell/element/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ impl Program for CosmicWindowInternal {
false,
&state.common.config,
&state.common.event_loop_handle,
true,
);

std::mem::drop(shell);
Expand Down
5 changes: 4 additions & 1 deletion src/shell/grabs/menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ impl Item {
}
}

/// Menu that comes up when right-clicking an application header bar
/// Menu that comes up when:
/// - Right-clicking an application header bar
/// - Super + Middle-clicking a window
/// - Super + Shift + Right-clicking a window
pub struct ContextMenu {
items: Vec<Item>,
selected: AtomicBool,
Expand Down
172 changes: 172 additions & 0 deletions src/shell/grabs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::cell::Cell;

use cosmic_settings_config::shortcuts;
use smithay::{
input::{
Expand Down Expand Up @@ -67,6 +69,176 @@ pub enum ReleaseMode {
NoMouseButtons,
}

#[derive(Debug, Clone)]
pub struct DistanceSwitchGrab<Moved: FnOnce(&mut State), Unmoved: FnOnce(&mut State)> {
pub moved: Option<Moved>,
pub unmoved: Option<Unmoved>,
pub start: GrabStartData,
pub pointer_moved_epsilon: u32,
}
impl<Moved: Send + 'static + FnOnce(&mut State), Unmoved: Send + 'static + FnOnce(&mut State)>
PointerGrab<State> for DistanceSwitchGrab<Moved, Unmoved>
{
fn motion(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
event: &MotionEvent,
) {
let start = self.start.location();
let current = event.location;

let x = start.x - current.x;
let y = start.y - current.y;

let distance = ((x * x) + (y * y)).sqrt();
if distance > self.pointer_moved_epsilon as f64 {
drop(data.common.shell.try_write().unwrap());
self.moved.take().unwrap()(data);
} else {
handle.motion(data, focus, event)
}
}

fn relative_motion(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
focus: Option<(
<State as smithay::input::SeatHandler>::PointerFocus,
Point<f64, Logical>,
)>,
event: &RelativeMotionEvent,
) {
handle.relative_motion(data, focus, event)
}

fn button(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &ButtonEvent,
) {
handle.button(data, event)
}

fn axis(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
details: AxisFrame,
) {
handle.axis(data, details)
}

fn frame(&mut self, data: &mut State, handle: &mut PointerInnerHandle<'_, State>) {
handle.frame(data)
}

fn gesture_swipe_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event)
}

fn gesture_swipe_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event)
}

fn gesture_swipe_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event)
}

fn gesture_pinch_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event)
}

fn gesture_pinch_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event)
}

fn gesture_pinch_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event)
}

fn gesture_hold_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event)
}

fn gesture_hold_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event)
}

fn start_data(&self) -> &PointerGrabStartData<State> {
match &self.start {
GrabStartData::Touch(_) => unreachable!(),
GrabStartData::Pointer(p) => p,
}
}

fn unset(&mut self, data: &mut State) {
if self.moved.is_some() {
self.unmoved.take().unwrap()(data);
}
_ = data;
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UngrabOnPointerUp(Cell<bool>);
impl UngrabOnPointerUp {
pub fn new() -> Self {
Self(Cell::new(false))
}

pub fn get(&self) -> bool {
self.0.get()
}

pub fn set(&self, ungrab: bool) {
self.0.set(ungrab);
}
}

mod menu;
pub use self::menu::*;
mod moving;
Expand Down
30 changes: 28 additions & 2 deletions src/shell/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use calloop::LoopHandle;
use focus::target::WindowGroup;
use grabs::SeatMoveGrabState;
use grabs::{DistanceSwitchGrab, SeatMoveGrabState};
use indexmap::IndexMap;
use layout::TilingExceptions;
use std::{
Expand Down Expand Up @@ -2564,10 +2564,11 @@ impl Shell {
target_stack: bool,
config: &Config,
evlh: &LoopHandle<'static, State>,
client_initiated: bool,
) -> Option<(MenuGrab, Focus)> {
let serial = serial.into();
let Some(GrabStartData::Pointer(start_data)) =
check_grab_preconditions(&seat, surface, serial, true)
check_grab_preconditions(&seat, surface, serial, client_initiated)
else {
return None;
};
Expand Down Expand Up @@ -2661,6 +2662,31 @@ impl Shell {
Some((grab, Focus::Keep))
}

pub fn distance_switch_request<Moved: FnOnce(&mut State), Unmoved: FnOnce(&mut State)>(
&mut self,
surface: &WlSurface,
seat: &Seat<State>,
serial: impl Into<Option<Serial>>,
config: &Config,
on_moved: Moved,
on_unmoved: Unmoved,
client_initiated: bool,
) -> Option<(DistanceSwitchGrab<Moved, Unmoved>, Focus)> {
let serial = serial.into();

let start_data = check_grab_preconditions(&seat, surface, serial, client_initiated)?;

Some((
DistanceSwitchGrab {
moved: Some(on_moved),
unmoved: Some(on_unmoved),
start: start_data,
pointer_moved_epsilon: config.cosmic_conf.pointer_moved_epsilon,
},
Focus::Keep,
))
}

pub fn move_request(
&mut self,
surface: &WlSurface,
Expand Down
1 change: 1 addition & 0 deletions src/wayland/handlers/xdg_shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ impl XdgShellHandler for State {
false,
&self.common.config,
&self.common.event_loop_handle,
true,
);
if let Some((grab, focus)) = res {
std::mem::drop(shell);
Expand Down
Loading