1
0
Fork 0
forked from wry/wry

tree: activate workspace on click

This commit is contained in:
Julian Orth 2022-05-17 18:58:30 +02:00
parent 70cc24107b
commit 858e777f5a
7 changed files with 127 additions and 13 deletions

View file

@ -373,6 +373,7 @@ fn create_dummy_output(state: &Rc<State>) {
is_dummy: true,
status: Default::default(),
scroll: Default::default(),
pointer_positions: Default::default(),
});
let dummy_workspace = Rc::new(WorkspaceNode {
id: state.node_ids.next(),

View file

@ -43,6 +43,7 @@ mod t0014_container_scroll_focus;
mod t0015_scroll_partial;
mod t0016_scroll_ws;
mod t0017_remove_unused_ws;
mod t0018_click_to_active_ws;
pub trait TestCase: Sync {
fn name(&self) -> &'static str;
@ -78,5 +79,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
t0015_scroll_partial,
t0016_scroll_ws,
t0017_remove_unused_ws,
t0018_click_to_active_ws,
}
}

View file

@ -0,0 +1,46 @@
use {
crate::{
ifs::wl_seat::BTN_LEFT,
it::{test_error::TestResult, testrun::TestRun},
},
std::rc::Rc,
};
testcase!();
async fn test(run: Rc<TestRun>) -> TestResult {
let ds = run.create_default_setup().await?;
run.cfg.show_workspace(ds.seat.id(), "1")?;
let client = run.create_client().await?;
let win1 = client.create_window().await?;
win1.map().await?;
run.cfg.show_workspace(ds.seat.id(), "2")?;
let win2 = client.create_window().await?;
win2.map().await?;
ds.mouse.abs(&ds.connector, 0.0, 0.0);
ds.mouse.click(BTN_LEFT);
client.sync().await;
let name = ds.output.workspace.get().map(|ws| ws.name.clone());
tassert_eq!(name.as_deref(), Some("1"));
let pos = {
let rd = ds.output.render_data.borrow_mut();
rd.titles.last().map(|t| t.x1).unwrap_or(0)
};
ds.mouse.abs(&ds.connector, pos as _, 0.0);
ds.mouse.click(BTN_LEFT);
client.sync().await;
let name = ds.output.workspace.get().map(|ws| ws.name.clone());
tassert_eq!(name.as_deref(), Some("2"));
Ok(())
}

View file

@ -114,10 +114,10 @@ impl Renderer<'_> {
let c = theme.colors.unfocused_title_background.get();
self.fill_boxes2(&rd.inactive_workspaces, &c, x, y);
for title in &rd.titles {
self.render_texture(&title.tex, x + title.x, y + title.y, ARGB8888);
self.render_texture(&title.tex, x + title.tex_x, y + title.tex_y, ARGB8888);
}
if let Some(status) = &rd.status {
self.render_texture(&status.tex, x + status.x, y + status.y, ARGB8888);
self.render_texture(&status.tex, x + status.tex_x, y + status.tex_y, ARGB8888);
}
}
if let Some(ws) = output.workspace.get() {

View file

@ -118,6 +118,7 @@ impl ConnectorHandler {
is_dummy: false,
status: self.state.status.clone(),
scroll: Default::default(),
pointer_positions: Default::default(),
});
let mode = info.initial_mode;
let output_data = Rc::new(OutputData {

View file

@ -1,10 +1,14 @@
use {
crate::{
backend::Mode,
backend::{KeyState, Mode},
cursor::KnownCursor,
fixed::Fixed,
ifs::{
wl_output::WlOutputGlobal,
wl_seat::{collect_kb_foci2, wl_pointer::PendingScroll, NodeSeatState, WlSeatGlobal},
wl_seat::{
collect_kb_foci2, wl_pointer::PendingScroll, NodeSeatState, SeatId, WlSeatGlobal,
BTN_LEFT,
},
wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
zwlr_layer_shell_v1::{BACKGROUND, BOTTOM, OVERLAY, TOP},
},
@ -16,7 +20,8 @@ use {
walker::NodeVisitor, Direction, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode,
},
utils::{
clonecell::CloneCell, errorfmt::ErrorFmt, linkedlist::LinkedList, scroller::Scroller,
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt,
linkedlist::LinkedList, scroller::Scroller,
},
},
smallvec::SmallVec,
@ -41,6 +46,7 @@ pub struct OutputNode {
pub is_dummy: bool,
pub status: CloneCell<Rc<String>>,
pub scroll: Scroller,
pub pointer_positions: CopyHashMap<SeatId, (i32, i32)>,
}
impl OutputNode {
@ -98,9 +104,12 @@ impl OutputNode {
x = pos + (title_width - title.width()) / 2;
}
rd.titles.push(OutputTitle {
x,
y: 0,
x1: pos,
x2: pos + title_width,
tex_x: x,
tex_y: 0,
tex: title,
ws: ws.deref().clone(),
});
}
}
@ -130,9 +139,9 @@ impl OutputNode {
}
};
let pos = width - title.width() - 1;
rd.status = Some(OutputTitle {
x: pos,
y: 0,
rd.status = Some(OutputStatus {
tex_x: pos,
tex_y: 0,
tex: title,
});
}
@ -295,11 +304,24 @@ impl OutputNode {
self.status.set(status.clone());
self.update_render_data();
}
fn pointer_move(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, x: i32, y: i32) {
self.pointer_positions.set(seat.id(), (x, y));
}
}
pub struct OutputTitle {
pub x: i32,
pub y: i32,
pub x1: i32,
pub x2: i32,
pub tex_x: i32,
pub tex_y: i32,
pub tex: Rc<Texture>,
pub ws: Rc<WorkspaceNode>,
}
pub struct OutputStatus {
pub tex_x: i32,
pub tex_y: i32,
pub tex: Rc<Texture>,
}
@ -309,7 +331,7 @@ pub struct OutputRenderData {
pub underline: Rect,
pub inactive_workspaces: Vec<Rect>,
pub titles: Vec<OutputTitle>,
pub status: Option<OutputTitle>,
pub status: Option<OutputStatus>,
}
impl Debug for OutputNode {
@ -423,6 +445,37 @@ impl Node for OutputNode {
renderer.render_output(self, x, y);
}
fn node_on_button(
self: Rc<Self>,
seat: &Rc<WlSeatGlobal>,
button: u32,
state: KeyState,
_serial: u32,
) {
if state != KeyState::Pressed || button != BTN_LEFT {
return;
}
let (x, y) = match self.pointer_positions.get(&seat.id()) {
Some(p) => p,
_ => return,
};
if y >= self.state.theme.sizes.title_height.get() {
return;
}
let ws = 'ws: {
let rd = self.render_data.borrow_mut();
for title in &rd.titles {
if x >= title.x1 && x < title.x2 {
break 'ws title.ws.clone();
}
}
return;
};
self.show_workspace(&ws);
self.update_render_data();
self.state.tree_changed();
}
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) {
let steps = match self.scroll.handle(event) {
Some(e) => e,
@ -460,11 +513,19 @@ impl Node for OutputNode {
self.state.tree_changed();
}
fn node_on_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
self.pointer_move(seat, x.round_down(), y.round_down());
}
fn node_on_pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
// log::info!("output focus");
seat.set_known_cursor(KnownCursor::Default);
}
fn node_on_pointer_motion(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
self.pointer_move(seat, x.round_down(), y.round_down());
}
fn node_into_output(self: Rc<Self>) -> Option<Rc<OutputNode>> {
Some(self.clone())
}

View file

@ -76,5 +76,8 @@ unsafe impl<T> UnsafeCellCloneSafe for NodeRef<T> {}
unsafe impl UnsafeCellCloneSafe for () {}
unsafe impl UnsafeCellCloneSafe for u64 {}
unsafe impl UnsafeCellCloneSafe for i32 {}
unsafe impl<A: UnsafeCellCloneSafe, B: UnsafeCellCloneSafe> UnsafeCellCloneSafe for (A, B) {}
unsafe impl UnsafeCellCloneSafe for Modifiers {}