element: Add cursor shape and resize handling on tool input
This commit is contained in:
parent
e65f6608a4
commit
b8824128a0
2 changed files with 144 additions and 7 deletions
|
|
@ -1938,7 +1938,17 @@ impl TabletToolTarget<State> for CosmicStack {
|
||||||
data: &mut State,
|
data: &mut State,
|
||||||
tool_descriptor: &TabletToolDescriptor,
|
tool_descriptor: &TabletToolDescriptor,
|
||||||
) {
|
) {
|
||||||
TabletToolTarget::proximity_out(&self.0, seat, data, tool_descriptor)
|
self.0.with_program(|p| {
|
||||||
|
let mut cursor_state = seat
|
||||||
|
.user_data()
|
||||||
|
.get::<CursorState>()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap();
|
||||||
|
cursor_state.unset_shape();
|
||||||
|
let _previous = p.swap_focus(None);
|
||||||
|
});
|
||||||
|
TabletToolTarget::proximity_out(&self.0, seat, data, tool_descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn down(
|
fn down(
|
||||||
|
|
@ -1948,7 +1958,50 @@ impl TabletToolTarget<State> for CosmicStack {
|
||||||
tool_descriptor: &TabletToolDescriptor,
|
tool_descriptor: &TabletToolDescriptor,
|
||||||
event: &ToolDownEvent,
|
event: &ToolDownEvent,
|
||||||
) {
|
) {
|
||||||
TabletToolTarget::down(&self.0, seat, data, tool_descriptor, event)
|
match self.0.with_program(|p| p.current_focus()) {
|
||||||
|
Some(Focus::Header) => {
|
||||||
|
TabletToolTarget::down(&self.0, seat, data, tool_descriptor, event)
|
||||||
|
}
|
||||||
|
Some(x) => {
|
||||||
|
let serial = event.serial;
|
||||||
|
let seat = seat.clone();
|
||||||
|
let Some(surface) = self.0.with_program(|p| {
|
||||||
|
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
|
||||||
|
window.wl_surface().map(Cow::into_owned)
|
||||||
|
}) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.0.loop_handle().insert_idle(move |state| {
|
||||||
|
let res = state.common.shell.write().resize_request(
|
||||||
|
&surface,
|
||||||
|
&seat,
|
||||||
|
serial,
|
||||||
|
match x {
|
||||||
|
Focus::ResizeTop => ResizeEdge::TOP,
|
||||||
|
Focus::ResizeTopLeft => ResizeEdge::TOP_LEFT,
|
||||||
|
Focus::ResizeTopRight => ResizeEdge::TOP_RIGHT,
|
||||||
|
Focus::ResizeBottom => ResizeEdge::BOTTOM,
|
||||||
|
Focus::ResizeBottomLeft => ResizeEdge::BOTTOM_LEFT,
|
||||||
|
Focus::ResizeBottomRight => ResizeEdge::BOTTOM_RIGHT,
|
||||||
|
Focus::ResizeLeft => ResizeEdge::LEFT,
|
||||||
|
Focus::ResizeRight => ResizeEdge::RIGHT,
|
||||||
|
Focus::Header => unreachable!(),
|
||||||
|
},
|
||||||
|
state.common.config.cosmic_conf.edge_snap_threshold,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
if let Some((grab, focus)) = res {
|
||||||
|
if let GrabType::TabletTool = grab.grab_type() {
|
||||||
|
seat.tablet_seat()
|
||||||
|
.get_tool(grab.tool().unwrap())
|
||||||
|
.unwrap()
|
||||||
|
.set_grab(state, grab, InputTime::now(), serial, focus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn up(
|
fn up(
|
||||||
|
|
@ -1969,12 +2022,30 @@ impl TabletToolTarget<State> for CosmicStack {
|
||||||
event: &ToolMotionEvent,
|
event: &ToolMotionEvent,
|
||||||
) {
|
) {
|
||||||
let mut event = event.clone();
|
let mut event = event.clone();
|
||||||
|
self.0.with_program(|p| {
|
||||||
|
let active = p.active.load(Ordering::SeqCst);
|
||||||
|
let active_window = &p.windows.lock().unwrap()[active];
|
||||||
|
let Some(next) = Focus::under(active_window, TAB_HEIGHT, event.location) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let _previous = p.swap_focus(Some(next));
|
||||||
|
|
||||||
|
let mut cursor_state = seat
|
||||||
|
.user_data()
|
||||||
|
.get::<CursorState>()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap();
|
||||||
|
cursor_state.set_shape(next.cursor_shape());
|
||||||
|
seat.set_cursor_image_status(CursorImageStatus::default_named());
|
||||||
|
});
|
||||||
|
|
||||||
let active_window_geo = self.0.with_program(|p| {
|
let active_window_geo = self.0.with_program(|p| {
|
||||||
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].geometry()
|
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].geometry()
|
||||||
});
|
});
|
||||||
event.location -= active_window_geo.loc.to_f64();
|
event.location -= active_window_geo.loc.to_f64();
|
||||||
TabletToolTarget::motion(&self.0, seat, data, tool_descriptor, &event);
|
|
||||||
|
|
||||||
|
TabletToolTarget::motion(&self.0, seat, data, tool_descriptor, &event);
|
||||||
if event.location.y < 0.0
|
if event.location.y < 0.0
|
||||||
|| event.location.y > TAB_HEIGHT as f64
|
|| event.location.y > TAB_HEIGHT as f64
|
||||||
|| event.location.x < 64.0
|
|| event.location.x < 64.0
|
||||||
|
|
|
||||||
|
|
@ -1032,8 +1032,7 @@ impl PointerTarget<State> for CosmicWindow {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let old_focus = p.swap_focus(Some(next));
|
let _ = p.swap_focus(Some(next));
|
||||||
assert_eq!(old_focus, None);
|
|
||||||
|
|
||||||
let cursor_state = seat.user_data().get::<CursorState>().unwrap();
|
let cursor_state = seat.user_data().get::<CursorState>().unwrap();
|
||||||
cursor_state.lock().unwrap().set_shape(next.cursor_shape());
|
cursor_state.lock().unwrap().set_shape(next.cursor_shape());
|
||||||
|
|
@ -1270,6 +1269,11 @@ impl TabletToolTarget<State> for CosmicWindow {
|
||||||
data: &mut State,
|
data: &mut State,
|
||||||
tool_descriptor: &TabletToolDescriptor,
|
tool_descriptor: &TabletToolDescriptor,
|
||||||
) {
|
) {
|
||||||
|
self.0.with_program(|p| {
|
||||||
|
let cursor_state = seat.user_data().get::<CursorState>().unwrap();
|
||||||
|
cursor_state.lock().unwrap().unset_shape();
|
||||||
|
let _previous = p.swap_focus(None);
|
||||||
|
});
|
||||||
TabletToolTarget::proximity_out(&self.0, seat, data, tool_descriptor)
|
TabletToolTarget::proximity_out(&self.0, seat, data, tool_descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1280,7 +1284,49 @@ impl TabletToolTarget<State> for CosmicWindow {
|
||||||
tool_descriptor: &TabletToolDescriptor,
|
tool_descriptor: &TabletToolDescriptor,
|
||||||
event: &ToolDownEvent,
|
event: &ToolDownEvent,
|
||||||
) {
|
) {
|
||||||
TabletToolTarget::down(&self.0, seat, data, tool_descriptor, event)
|
match self.0.with_program(|p| p.current_focus()) {
|
||||||
|
Some(Focus::Header) => {
|
||||||
|
TabletToolTarget::down(&self.0, seat, data, tool_descriptor, event)
|
||||||
|
}
|
||||||
|
Some(x) => {
|
||||||
|
let serial = event.serial;
|
||||||
|
let seat = seat.clone();
|
||||||
|
let Some(surface) = self.wl_surface().map(Cow::into_owned) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.0.loop_handle().insert_idle(move |state| {
|
||||||
|
let res = state.common.shell.write().resize_request(
|
||||||
|
&surface,
|
||||||
|
&seat,
|
||||||
|
serial,
|
||||||
|
match x {
|
||||||
|
Focus::ResizeTop => ResizeEdge::TOP,
|
||||||
|
Focus::ResizeTopLeft => ResizeEdge::TOP_LEFT,
|
||||||
|
Focus::ResizeTopRight => ResizeEdge::TOP_RIGHT,
|
||||||
|
Focus::ResizeBottom => ResizeEdge::BOTTOM,
|
||||||
|
Focus::ResizeBottomLeft => ResizeEdge::BOTTOM_LEFT,
|
||||||
|
Focus::ResizeBottomRight => ResizeEdge::BOTTOM_RIGHT,
|
||||||
|
Focus::ResizeLeft => ResizeEdge::LEFT,
|
||||||
|
Focus::ResizeRight => ResizeEdge::RIGHT,
|
||||||
|
Focus::Header => unreachable!(),
|
||||||
|
},
|
||||||
|
state.common.config.cosmic_conf.edge_snap_threshold,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some((grab, focus)) = res {
|
||||||
|
if let GrabType::TabletTool = grab.grab_type() {
|
||||||
|
seat.tablet_seat()
|
||||||
|
.get_tool(grab.tool().unwrap())
|
||||||
|
.unwrap()
|
||||||
|
.set_grab(state, grab, InputTime::now(), serial, focus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn up(
|
fn up(
|
||||||
|
|
@ -1300,7 +1346,27 @@ impl TabletToolTarget<State> for CosmicWindow {
|
||||||
tool_descriptor: &TabletToolDescriptor,
|
tool_descriptor: &TabletToolDescriptor,
|
||||||
event: &ToolMotionEvent,
|
event: &ToolMotionEvent,
|
||||||
) {
|
) {
|
||||||
TabletToolTarget::motion(&self.0, seat, data, tool_descriptor, event)
|
let mut event = event.clone();
|
||||||
|
self.0.with_program(|p| {
|
||||||
|
let has_ssd = p.has_ssd(false);
|
||||||
|
if has_ssd || p.has_tiled_state() {
|
||||||
|
let Some(next) = Focus::under(
|
||||||
|
&p.window,
|
||||||
|
if has_ssd { SSD_HEIGHT } else { 0 },
|
||||||
|
event.location,
|
||||||
|
) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let _previous = p.swap_focus(Some(next));
|
||||||
|
|
||||||
|
let cursor_state = seat.user_data().get::<CursorState>().unwrap();
|
||||||
|
cursor_state.lock().unwrap().set_shape(next.cursor_shape());
|
||||||
|
seat.set_cursor_image_status(CursorImageStatus::default_named());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
event.location -= self.0.with_program(|p| p.window.geometry().loc.to_f64());
|
||||||
|
TabletToolTarget::motion(&self.0, seat, data, tool_descriptor, &event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn axis(
|
fn axis(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue