tree: allow focusing workspace nodes
This commit is contained in:
parent
dd3f8bad40
commit
5bb19f3ca7
12 changed files with 76 additions and 22 deletions
|
|
@ -728,6 +728,7 @@ fn create_dummy_output(state: &Rc<State>) {
|
||||||
bar_rect: Default::default(),
|
bar_rect: Default::default(),
|
||||||
bar_rect_rel: Default::default(),
|
bar_rect_rel: Default::default(),
|
||||||
bar_rect_with_separator: Default::default(),
|
bar_rect_with_separator: Default::default(),
|
||||||
|
bar_separator_rect: Default::default(),
|
||||||
bar_separator_rect_rel: Default::default(),
|
bar_separator_rect_rel: Default::default(),
|
||||||
non_exclusive_rect: Default::default(),
|
non_exclusive_rect: Default::default(),
|
||||||
render_data: Default::default(),
|
render_data: Default::default(),
|
||||||
|
|
|
||||||
|
|
@ -740,7 +740,16 @@ impl WlSeatGlobal {
|
||||||
pub fn move_focus(self: &Rc<Self>, direction: Direction) {
|
pub fn move_focus(self: &Rc<Self>, direction: Direction) {
|
||||||
let tl = match self.keyboard_node.get().node_toplevel() {
|
let tl = match self.keyboard_node.get().node_toplevel() {
|
||||||
Some(tl) => tl,
|
Some(tl) => tl,
|
||||||
_ => return,
|
_ => {
|
||||||
|
if let Some(ws) = self.keyboard_node.get().node_into_workspace()
|
||||||
|
&& let Some(target) = self
|
||||||
|
.state
|
||||||
|
.find_output_in_direction(&ws.output.get(), direction)
|
||||||
|
{
|
||||||
|
target.take_keyboard_navigation_focus(self, direction);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if direction == Direction::Down && tl.node_is_container() {
|
if direction == Direction::Down && tl.node_is_container() {
|
||||||
tl.node_do_focus(self, direction);
|
tl.node_do_focus(self, direction);
|
||||||
|
|
@ -762,6 +771,13 @@ impl WlSeatGlobal {
|
||||||
pub fn move_focused(self: &Rc<Self>, direction: Direction) {
|
pub fn move_focused(self: &Rc<Self>, direction: Direction) {
|
||||||
let kb_node = self.keyboard_node.get();
|
let kb_node = self.keyboard_node.get();
|
||||||
let Some(tl) = kb_node.node_toplevel() else {
|
let Some(tl) = kb_node.node_toplevel() else {
|
||||||
|
if let Some(ws) = self.keyboard_node.get().node_into_workspace()
|
||||||
|
&& let Some(target) = self
|
||||||
|
.state
|
||||||
|
.find_output_in_direction(&ws.output.get(), direction)
|
||||||
|
{
|
||||||
|
self.state.move_ws_to_output(&ws, &target);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let data = tl.tl_data();
|
let data = tl.tl_data();
|
||||||
|
|
@ -995,7 +1011,15 @@ impl WlSeatGlobal {
|
||||||
NodeLayer::Layer0 => handle_layer_shell(&output.layers[0]),
|
NodeLayer::Layer0 => handle_layer_shell(&output.layers[0]),
|
||||||
NodeLayer::Layer1 => handle_layer_shell(&output.layers[1]),
|
NodeLayer::Layer1 => handle_layer_shell(&output.layers[1]),
|
||||||
NodeLayer::Output => None,
|
NodeLayer::Output => None,
|
||||||
NodeLayer::Workspace => None,
|
NodeLayer::Workspace => {
|
||||||
|
if let Some(ws) = &ws
|
||||||
|
&& ws.container_visible()
|
||||||
|
{
|
||||||
|
self.focus_node(ws.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
NodeLayer::Tiled => ws
|
NodeLayer::Tiled => ws
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|w| w.container.get())
|
.and_then(|w| w.container.get())
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -18,6 +18,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
win1.set_color(255, 0, 0, 255);
|
win1.set_color(255, 0, 0, 255);
|
||||||
win1.map2().await?;
|
win1.map2().await?;
|
||||||
run.cfg.set_floating(ds.seat.id(), true)?;
|
run.cfg.set_floating(ds.seat.id(), true)?;
|
||||||
|
client.sync().await;
|
||||||
|
|
||||||
for i in ["1", "2"] {
|
for i in ["1", "2"] {
|
||||||
let (x, y) = win1.tl.server.node_absolute_position().position();
|
let (x, y) = win1.tl.server.node_absolute_position().position();
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -85,6 +85,7 @@ impl Renderer<'_> {
|
||||||
} else {
|
} else {
|
||||||
render_layer!(output.layers[0]);
|
render_layer!(output.layers[0]);
|
||||||
render_layer!(output.layers[1]);
|
render_layer!(output.layers[1]);
|
||||||
|
let ws = output.workspace.get();
|
||||||
if self.state.show_bar.get() {
|
if self.state.show_bar.get() {
|
||||||
let non_exclusive_rect_rel = output.non_exclusive_rect_rel.get();
|
let non_exclusive_rect_rel = output.non_exclusive_rect_rel.get();
|
||||||
let (mut x, mut y) = non_exclusive_rect_rel.translate_inv(x, y);
|
let (mut x, mut y) = non_exclusive_rect_rel.translate_inv(x, y);
|
||||||
|
|
@ -109,7 +110,12 @@ impl Renderer<'_> {
|
||||||
self.base
|
self.base
|
||||||
.fill_boxes2(slice::from_ref(&aw.rect), &c, srgb, x, y);
|
.fill_boxes2(slice::from_ref(&aw.rect), &c, srgb, x, y);
|
||||||
}
|
}
|
||||||
let c = theme.colors.separator.get();
|
let mut c = theme.colors.separator.get();
|
||||||
|
if let Some(ws) = &ws
|
||||||
|
&& ws.seat_state.is_active()
|
||||||
|
{
|
||||||
|
c = theme.colors.focused_title_background.get();
|
||||||
|
}
|
||||||
self.base
|
self.base
|
||||||
.fill_boxes2(slice::from_ref(&rd.bar_separator), &c, srgb, x, y);
|
.fill_boxes2(slice::from_ref(&rd.bar_separator), &c, srgb, x, y);
|
||||||
let c = theme.colors.unfocused_title_background.get();
|
let c = theme.colors.unfocused_title_background.get();
|
||||||
|
|
@ -172,7 +178,7 @@ impl Renderer<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ws) = output.workspace.get() {
|
if let Some(ws) = &ws {
|
||||||
let ws_rect = output.workspace_rect_rel.get();
|
let ws_rect = output.workspace_rect_rel.get();
|
||||||
let (x, y) = ws_rect.translate_inv(x, y);
|
let (x, y) = ws_rect.translate_inv(x, y);
|
||||||
self.render_workspace(&ws, x, y);
|
self.render_workspace(&ws, x, y);
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ impl ConnectorHandler {
|
||||||
bar_rect: Default::default(),
|
bar_rect: Default::default(),
|
||||||
bar_rect_rel: Default::default(),
|
bar_rect_rel: Default::default(),
|
||||||
bar_rect_with_separator: Default::default(),
|
bar_rect_with_separator: Default::default(),
|
||||||
|
bar_separator_rect: Default::default(),
|
||||||
bar_separator_rect_rel: Default::default(),
|
bar_separator_rect_rel: Default::default(),
|
||||||
render_data: Default::default(),
|
render_data: Default::default(),
|
||||||
state: self.state.clone(),
|
state: self.state.clone(),
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ pub struct OutputNode {
|
||||||
pub bar_rect: Cell<Rect>,
|
pub bar_rect: Cell<Rect>,
|
||||||
pub bar_rect_rel: Cell<Rect>,
|
pub bar_rect_rel: Cell<Rect>,
|
||||||
pub bar_rect_with_separator: Cell<Rect>,
|
pub bar_rect_with_separator: Cell<Rect>,
|
||||||
|
pub bar_separator_rect: Cell<Rect>,
|
||||||
pub bar_separator_rect_rel: Cell<Rect>,
|
pub bar_separator_rect_rel: Cell<Rect>,
|
||||||
pub render_data: RefCell<OutputRenderData>,
|
pub render_data: RefCell<OutputRenderData>,
|
||||||
pub state: Rc<State>,
|
pub state: Rc<State>,
|
||||||
|
|
@ -774,11 +775,11 @@ impl OutputNode {
|
||||||
let mut bar_rect = Rect::default();
|
let mut bar_rect = Rect::default();
|
||||||
let mut bar_rect_rel = Rect::default();
|
let mut bar_rect_rel = Rect::default();
|
||||||
let mut bar_rect_with_separator = Rect::default();
|
let mut bar_rect_with_separator = Rect::default();
|
||||||
|
let mut bar_separator_rect = Rect::default();
|
||||||
let mut bar_separator_rect_rel = Rect::default();
|
let mut bar_separator_rect_rel = Rect::default();
|
||||||
let mut workspace_rect = non_exclusive_rect;
|
let mut workspace_rect = non_exclusive_rect;
|
||||||
let mut workspace_rect_rel = non_exclusive_rect_rel;
|
let mut workspace_rect_rel = non_exclusive_rect_rel;
|
||||||
if self.state.show_bar.get() {
|
if self.state.show_bar.get() {
|
||||||
let bar_separator_rect;
|
|
||||||
match self.state.theme.bar_position.get() {
|
match self.state.theme.bar_position.get() {
|
||||||
BarPosition::Bottom => {
|
BarPosition::Bottom => {
|
||||||
workspace_rect = Rect::new_sized_saturating(x1, y1, width, height - bh - bsw);
|
workspace_rect = Rect::new_sized_saturating(x1, y1, width, height - bh - bsw);
|
||||||
|
|
@ -805,6 +806,7 @@ impl OutputNode {
|
||||||
self.bar_rect.set(bar_rect);
|
self.bar_rect.set(bar_rect);
|
||||||
self.bar_rect_rel.set(bar_rect_rel);
|
self.bar_rect_rel.set(bar_rect_rel);
|
||||||
self.bar_rect_with_separator.set(bar_rect_with_separator);
|
self.bar_rect_with_separator.set(bar_rect_with_separator);
|
||||||
|
self.bar_separator_rect.set(bar_separator_rect);
|
||||||
self.bar_separator_rect_rel.set(bar_separator_rect_rel);
|
self.bar_separator_rect_rel.set(bar_separator_rect_rel);
|
||||||
self.workspace_rect.set(workspace_rect);
|
self.workspace_rect.set(workspace_rect);
|
||||||
self.workspace_rect_rel.set(workspace_rect_rel);
|
self.workspace_rect_rel.set(workspace_rect_rel);
|
||||||
|
|
@ -1147,20 +1149,13 @@ impl OutputNode {
|
||||||
set_layer_visible!(self.layers[3], visible);
|
set_layer_visible!(self.layers[3], visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, id: PointerType) {
|
fn bar_button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, x: i32, y: i32) -> bool {
|
||||||
if !self.state.show_bar.get() {
|
if !self.state.show_bar.get() {
|
||||||
return;
|
return false;
|
||||||
}
|
|
||||||
let (x, y) = match self.pointer_positions.get(&id) {
|
|
||||||
Some(p) => p,
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
if let PointerType::Seat(s) = id {
|
|
||||||
self.pointer_down.set(s, (x, y));
|
|
||||||
}
|
}
|
||||||
let bar_rect_rel = self.bar_rect_rel.get();
|
let bar_rect_rel = self.bar_rect_rel.get();
|
||||||
if bar_rect_rel.not_contains(x, y) {
|
if bar_rect_rel.not_contains(x, y) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
let (x, _) = bar_rect_rel.translate(x, y);
|
let (x, _) = bar_rect_rel.translate(x, y);
|
||||||
let ws = 'ws: {
|
let ws = 'ws: {
|
||||||
|
|
@ -1170,9 +1165,25 @@ impl OutputNode {
|
||||||
break 'ws title.ws.clone();
|
break 'ws title.ws.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
};
|
};
|
||||||
self.state.show_workspace2(Some(seat), &self, &ws);
|
self.state.show_workspace2(Some(seat), self, &ws);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, id: PointerType) {
|
||||||
|
let (x, y) = match self.pointer_positions.get(&id) {
|
||||||
|
Some(p) => p,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
if let PointerType::Seat(s) = id {
|
||||||
|
self.pointer_down.set(s, (x, y));
|
||||||
|
}
|
||||||
|
if self.bar_button(seat, x, y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let ws = self.ensure_workspace();
|
||||||
|
seat.focus_node(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_presentation_type(&self) {
|
pub fn update_presentation_type(&self) {
|
||||||
|
|
@ -1489,6 +1500,10 @@ impl OutputNode {
|
||||||
if c.node_visible() {
|
if c.node_visible() {
|
||||||
c.node_do_focus(seat, direction);
|
c.node_do_focus(seat, direction);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if ws.node_visible() {
|
||||||
|
seat.focus_node(ws);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,17 +366,23 @@ impl Node for WorkspaceNode {
|
||||||
seat.focus_node(last);
|
seat.focus_node(last);
|
||||||
} else if let Some(container) = self.container.get() {
|
} else if let Some(container) = self.container.get() {
|
||||||
container.node_do_focus(seat, direction);
|
container.node_do_focus(seat, direction);
|
||||||
} else if let Some(float) = self
|
} else if let Some(child) = self
|
||||||
.stacked
|
.stacked
|
||||||
.rev_iter()
|
.rev_iter()
|
||||||
.find_map(|node| (*node).clone().node_into_float())
|
.filter_map(|node| (*node).clone().node_into_float())
|
||||||
|
.find_map(|float| float.child.get())
|
||||||
{
|
{
|
||||||
if let Some(child) = float.child.get() {
|
child.node_do_focus(seat, direction);
|
||||||
child.node_do_focus(seat, direction);
|
} else {
|
||||||
}
|
seat.focus_node(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn node_active_changed(&self, _active: bool) {
|
||||||
|
let output = self.output.get();
|
||||||
|
self.state.damage(output.bar_separator_rect.get());
|
||||||
|
}
|
||||||
|
|
||||||
fn node_find_tree_at(
|
fn node_find_tree_at(
|
||||||
&self,
|
&self,
|
||||||
x: i32,
|
x: i32,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue