config: add create-mark, jump-to-mark, and copy-mark actions
This commit is contained in:
parent
e30e2595a1
commit
eb625b34cc
19 changed files with 1193 additions and 9 deletions
|
|
@ -76,6 +76,7 @@ use {
|
|||
window::{TileState, Window, WindowMatcher},
|
||||
xwayland::XScalingMode,
|
||||
},
|
||||
kbvm::Keycode,
|
||||
libloading::Library,
|
||||
log::Level,
|
||||
regex::Regex,
|
||||
|
|
@ -2208,6 +2209,32 @@ impl ConfigProxyHandler {
|
|||
self.state.enable_primary_selection.set(enabled);
|
||||
}
|
||||
|
||||
fn handle_seat_create_mark(&self, seat: Seat, kc: Option<u32>) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
if let Some(kc) = kc {
|
||||
seat.create_mark(Keycode::from_evdev(kc));
|
||||
} else {
|
||||
seat.create_mark_interactive();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_seat_jump_to_mark(&self, seat: Seat, kc: Option<u32>) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
if let Some(kc) = kc {
|
||||
seat.jump_to_mark(Keycode::from_evdev(kc));
|
||||
} else {
|
||||
seat.jump_to_mark_interactive();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_seat_copy_mark(&self, seat: Seat, src: u32, dst: u32) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
seat.copy_mark(Keycode::from_evdev(src), Keycode::from_evdev(dst));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn spaces_change(&self) {
|
||||
struct V;
|
||||
impl NodeVisitorBase for V {
|
||||
|
|
@ -3071,6 +3098,15 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::SetMiddleClickPasteEnabled { enabled } => {
|
||||
self.handle_set_middle_click_paste_enabled(enabled)
|
||||
}
|
||||
ClientMessage::SeatCreateMark { seat, kc } => self
|
||||
.handle_seat_create_mark(seat, kc)
|
||||
.wrn("seat_create_mark")?,
|
||||
ClientMessage::SeatJumpToMark { seat, kc } => self
|
||||
.handle_seat_jump_to_mark(seat, kc)
|
||||
.wrn("seat_jump_to_mark")?,
|
||||
ClientMessage::SeatCopyMark { seat, src, dst } => self
|
||||
.handle_seat_copy_mark(seat, src, dst)
|
||||
.wrn("seat_copy_mark")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ use {
|
|||
},
|
||||
ahash::AHashMap,
|
||||
jay_config::keyboard::syms::{KeySym, SYM_Escape},
|
||||
kbvm::Keycode,
|
||||
smallvec::SmallVec,
|
||||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
|
|
@ -232,6 +233,14 @@ pub struct WlSeatGlobal {
|
|||
focus_history_rotate: NumCell<u64>,
|
||||
focus_history_visible_only: Cell<bool>,
|
||||
focus_history_same_workspace: Cell<bool>,
|
||||
mark_mode: Cell<Option<MarkMode>>,
|
||||
marks: CopyHashMap<Keycode, Rc<dyn Node>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum MarkMode {
|
||||
Mark,
|
||||
Jump,
|
||||
}
|
||||
|
||||
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
||||
|
|
@ -311,6 +320,8 @@ impl WlSeatGlobal {
|
|||
focus_history_rotate: Default::default(),
|
||||
focus_history_visible_only: Cell::new(false),
|
||||
focus_history_same_workspace: Cell::new(false),
|
||||
mark_mode: Default::default(),
|
||||
marks: Default::default(),
|
||||
});
|
||||
slf.pointer_cursor.set_owner(slf.clone());
|
||||
let seat = slf.clone();
|
||||
|
|
@ -1186,6 +1197,7 @@ impl WlSeatGlobal {
|
|||
self.cursor_user_group.detach();
|
||||
self.tablet_clear();
|
||||
self.ei_seats.clear();
|
||||
self.marks.clear();
|
||||
}
|
||||
|
||||
pub fn id(&self) -> SeatId {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use {
|
|||
},
|
||||
},
|
||||
wl_seat::{
|
||||
CHANGE_CURSOR_MOVED, CHANGE_TREE, Dnd, SeatId, WlSeat, WlSeatGlobal,
|
||||
CHANGE_CURSOR_MOVED, CHANGE_TREE, Dnd, MarkMode, SeatId, WlSeat, WlSeatGlobal,
|
||||
tablet::{TabletPad, TabletPadId, TabletTool, TabletToolId},
|
||||
text_input::TextDisconnectReason,
|
||||
wl_keyboard::WlKeyboard,
|
||||
|
|
@ -56,7 +56,7 @@ use {
|
|||
syms::KeySym,
|
||||
},
|
||||
},
|
||||
kbvm::{ModifierMask, state_machine::Event},
|
||||
kbvm::{Keycode, ModifierMask, evdev, state_machine::Event},
|
||||
linearize::LinearizeExt,
|
||||
smallvec::SmallVec,
|
||||
std::{
|
||||
|
|
@ -80,6 +80,12 @@ pub struct NodeSeatState {
|
|||
tablet_pad_foci: SmallMap<TabletPadId, Rc<TabletPad>, 1>,
|
||||
tablet_tool_foci: SmallMap<TabletToolId, Rc<TabletTool>, 1>,
|
||||
ui_drags: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
marks: RefCell<SmallMapMut<SeatId, Marks, 1>>,
|
||||
}
|
||||
|
||||
struct Marks {
|
||||
seat: Rc<WlSeatGlobal>,
|
||||
marks: SmallMapMut<Keycode, (), 1>,
|
||||
}
|
||||
|
||||
pub struct FocusHistoryData {
|
||||
|
|
@ -217,6 +223,12 @@ impl NodeSeatState {
|
|||
entry.visible.set(false);
|
||||
entry.detach();
|
||||
}
|
||||
for (_, marks) in self.marks.borrow_mut().iter_mut() {
|
||||
for (kc, _) in &marks.marks {
|
||||
marks.seat.marks.remove(kc);
|
||||
}
|
||||
marks.marks.clear();
|
||||
}
|
||||
self.destroy_node2(node, true);
|
||||
}
|
||||
|
||||
|
|
@ -870,6 +882,23 @@ impl WlSeatGlobal {
|
|||
KeyState::Pressed => pk.insert(kc.to_evdev()),
|
||||
}
|
||||
};
|
||||
if key_state == KeyState::Pressed
|
||||
&& let Some(mode) = self.mark_mode.take()
|
||||
{
|
||||
update_pressed_keys(&mut kbvm_state);
|
||||
if kc == evdev::ESC {
|
||||
continue;
|
||||
}
|
||||
match mode {
|
||||
MarkMode::Mark => self.create_mark(kc),
|
||||
MarkMode::Jump => {
|
||||
drop(kbvm_state);
|
||||
self.jump_to_mark(kc);
|
||||
kbvm_state = kbvm_state_rc.borrow_mut();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
shortcuts.clear();
|
||||
{
|
||||
let mut mods = kbvm_state.kb_state.mods.mods.0 & !(CAPS.0 | NUM.0);
|
||||
|
|
@ -949,6 +978,60 @@ impl WlSeatGlobal {
|
|||
self.send_components(&mut components_changed, &kbvm_state);
|
||||
}
|
||||
|
||||
pub fn create_mark_interactive(&self) {
|
||||
self.mark_mode.set(Some(MarkMode::Mark));
|
||||
}
|
||||
|
||||
pub fn create_mark(self: &Rc<Self>, kc: Keycode) {
|
||||
self.create_mark_(kc, self.keyboard_node.get());
|
||||
}
|
||||
|
||||
fn create_mark_(self: &Rc<Self>, kc: Keycode, node: Rc<dyn Node>) {
|
||||
let prev = self.marks.set(kc, node.clone());
|
||||
if let Some(prev) = prev {
|
||||
if prev.node_id() == node.node_id() {
|
||||
return;
|
||||
}
|
||||
if let Some(marks) = prev.node_seat_state().marks.borrow_mut().get_mut(&self.id) {
|
||||
marks.marks.remove(&kc);
|
||||
}
|
||||
}
|
||||
node.node_seat_state()
|
||||
.marks
|
||||
.borrow_mut()
|
||||
.get_or_insert_with(self.id, || Marks {
|
||||
seat: self.clone(),
|
||||
marks: Default::default(),
|
||||
})
|
||||
.marks
|
||||
.insert(kc, ());
|
||||
}
|
||||
|
||||
pub fn jump_to_mark_interactive(&self) {
|
||||
self.mark_mode.set(Some(MarkMode::Jump));
|
||||
}
|
||||
|
||||
pub fn jump_to_mark(self: &Rc<Self>, kc: Keycode) {
|
||||
if let Some(node) = self.marks.get(&kc)
|
||||
&& node.node_accepts_focus()
|
||||
&& node.node_id() != self.keyboard_node.get().node_id()
|
||||
{
|
||||
if !node.node_visible() {
|
||||
node.clone().node_make_visible();
|
||||
if !node.node_visible() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.focus_node(node);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_mark(self: &Rc<Self>, src: Keycode, dst: Keycode) {
|
||||
if let Some(node) = self.marks.get(&src) {
|
||||
self.create_mark_(dst, node);
|
||||
}
|
||||
}
|
||||
|
||||
fn send_components(&self, components_changed: &mut bool, kbvm_state: &KbvmState) {
|
||||
if !mem::take(components_changed) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -198,6 +198,15 @@ impl<K: Eq, V, const N: usize> SmallMapMut<K, V, N> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
|
||||
for (ek, ev) in &mut self.m {
|
||||
if ek == k {
|
||||
return Some(ev);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_or_default_mut(&mut self, k: K) -> &mut V
|
||||
where
|
||||
V: Default,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue