Merge pull request #121 from mahkoh/jorth/input-region
tree: implement surface input regions
This commit is contained in:
commit
1540b4e90f
7 changed files with 58 additions and 33 deletions
|
|
@ -134,7 +134,7 @@ pub struct WlSurface {
|
||||||
visible: Cell<bool>,
|
visible: Cell<bool>,
|
||||||
role: Cell<SurfaceRole>,
|
role: Cell<SurfaceRole>,
|
||||||
pending: PendingState,
|
pending: PendingState,
|
||||||
input_region: Cell<Option<Rc<Region>>>,
|
input_region: CloneCell<Option<Rc<Region>>>,
|
||||||
opaque_region: Cell<Option<Rc<Region>>>,
|
opaque_region: Cell<Option<Rc<Region>>>,
|
||||||
buffer_points: RefCell<BufferPoints>,
|
buffer_points: RefCell<BufferPoints>,
|
||||||
pub buffer_points_norm: RefCell<SampleRect>,
|
pub buffer_points_norm: RefCell<SampleRect>,
|
||||||
|
|
@ -894,13 +894,25 @@ impl WlSurface {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_surface_at(self: &Rc<Self>, x: i32, y: i32) -> Option<(Rc<Self>, i32, i32)> {
|
fn accepts_input_at(&self, x: i32, y: i32) -> bool {
|
||||||
let rect = self.buffer_abs_pos.get().at_point(0, 0);
|
let rect = self.buffer_abs_pos.get().at_point(0, 0);
|
||||||
|
if !rect.contains(x, y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let Some(ir) = self.input_region.get() {
|
||||||
|
if !ir.contains(x, y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_surface_at(self: &Rc<Self>, x: i32, y: i32) -> Option<(Rc<Self>, i32, i32)> {
|
||||||
let children = self.children.borrow();
|
let children = self.children.borrow();
|
||||||
let children = match children.deref() {
|
let children = match children.deref() {
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
_ => {
|
_ => {
|
||||||
return if rect.contains(x, y) {
|
return if self.accepts_input_at(x, y) {
|
||||||
Some((self.clone(), x, y))
|
Some((self.clone(), x, y))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -925,7 +937,7 @@ impl WlSurface {
|
||||||
if let Some(res) = ss(&children.above) {
|
if let Some(res) = ss(&children.above) {
|
||||||
return Some(res);
|
return Some(res);
|
||||||
}
|
}
|
||||||
if rect.contains(x, y) {
|
if self.accepts_input_at(x, y) {
|
||||||
return Some((self.clone(), x, y));
|
return Some((self.clone(), x, y));
|
||||||
}
|
}
|
||||||
if let Some(res) = ss(&children.below) {
|
if let Some(res) = ss(&children.below) {
|
||||||
|
|
|
||||||
|
|
@ -322,6 +322,10 @@ impl Node for Xwindow {
|
||||||
seat.focus_toplevel(self.clone());
|
seat.focus_toplevel(self.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn node_active_changed(&self, active: bool) {
|
||||||
|
self.toplevel_data.update_self_active(self, active);
|
||||||
|
}
|
||||||
|
|
||||||
fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
let rect = self.x.surface.buffer_abs_pos.get();
|
let rect = self.x.surface.buffer_abs_pos.get();
|
||||||
if x < rect.width() && y < rect.height() {
|
if x < rect.width() && y < rect.height() {
|
||||||
|
|
|
||||||
|
|
@ -511,6 +511,10 @@ impl Node for XdgToplevel {
|
||||||
seat.focus_toplevel(self.clone());
|
seat.focus_toplevel(self.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn node_active_changed(&self, active: bool) {
|
||||||
|
self.toplevel_data.update_self_active(self, active);
|
||||||
|
}
|
||||||
|
|
||||||
fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
self.xdg.find_tree_at(x, y, tree)
|
self.xdg.find_tree_at(x, y, tree)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -758,7 +758,9 @@ impl ContainerNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mono_child.set(Some(child.clone()));
|
self.mono_child.set(Some(child.clone()));
|
||||||
child.node.tl_set_visible(true);
|
if self.toplevel_data.visible.get() {
|
||||||
|
child.node.tl_set_visible(true);
|
||||||
|
}
|
||||||
child.node.tl_restack_popups();
|
child.node.tl_restack_popups();
|
||||||
// log::info!("activate_child2");
|
// log::info!("activate_child2");
|
||||||
self.schedule_layout();
|
self.schedule_layout();
|
||||||
|
|
@ -1126,10 +1128,7 @@ impl Node for ContainerNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_active_changed(&self, active: bool) {
|
fn node_active_changed(&self, active: bool) {
|
||||||
self.toplevel_data.active.set(active);
|
self.toplevel_data.update_self_active(self, active);
|
||||||
if let Some(parent) = self.toplevel_data.parent.get() {
|
|
||||||
parent.node_child_active_changed(self, active, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ use {
|
||||||
state::State,
|
state::State,
|
||||||
text::{self, TextTexture},
|
text::{self, TextTexture},
|
||||||
tree::{
|
tree::{
|
||||||
walker::NodeVisitor, ContainingNode, FindTreeResult, FoundNode, Node, NodeId,
|
walker::NodeVisitor, ContainingNode, Direction, FindTreeResult, FoundNode, Node,
|
||||||
StackedNode, ToplevelNode, WorkspaceNode,
|
NodeId, StackedNode, ToplevelNode, WorkspaceNode,
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{
|
||||||
clonecell::CloneCell, copyhashmap::CopyHashMap, double_click_state::DoubleClickState,
|
clonecell::CloneCell, copyhashmap::CopyHashMap, double_click_state::DoubleClickState,
|
||||||
|
|
@ -490,6 +490,11 @@ impl Node for FloatNode {
|
||||||
if state != KeyState::Pressed {
|
if state != KeyState::Pressed {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if seat_data.op_type == OpType::Move {
|
||||||
|
if let Some(tl) = self.child.get() {
|
||||||
|
tl.node_do_focus(seat, Direction::Unspecified);
|
||||||
|
}
|
||||||
|
}
|
||||||
if seat_data
|
if seat_data
|
||||||
.double_click_state
|
.double_click_state
|
||||||
.click(&self.state, time_usec, seat_data.x, seat_data.y)
|
.click(&self.state, time_usec, seat_data.x, seat_data.y)
|
||||||
|
|
|
||||||
|
|
@ -113,10 +113,7 @@ impl Node for PlaceholderNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_active_changed(&self, active: bool) {
|
fn node_active_changed(&self, active: bool) {
|
||||||
self.toplevel.active.set(active);
|
self.toplevel.update_self_active(self, active);
|
||||||
if let Some(parent) = self.toplevel.parent.get() {
|
|
||||||
parent.node_child_active_changed(self, active, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_find_tree_at(&self, _x: i32, _y: i32, _tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn node_find_tree_at(&self, _x: i32, _y: i32, _tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
|
|
|
||||||
|
|
@ -58,21 +58,9 @@ impl<T: ToplevelNodeBase> ToplevelNode for T {
|
||||||
|
|
||||||
fn tl_surface_active_changed(&self, active: bool) {
|
fn tl_surface_active_changed(&self, active: bool) {
|
||||||
let data = self.tl_data();
|
let data = self.tl_data();
|
||||||
if active {
|
data.update_active(self, || {
|
||||||
if data.active_surfaces.inc() {
|
data.active_surfaces.adj(active);
|
||||||
self.tl_set_active(true);
|
});
|
||||||
if let Some(parent) = data.parent.get() {
|
|
||||||
parent.node_child_active_changed(self.tl_as_node(), true, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if data.active_surfaces.dec() {
|
|
||||||
self.tl_set_active(false);
|
|
||||||
if let Some(parent) = data.parent.get() {
|
|
||||||
parent.node_child_active_changed(self.tl_as_node(), false, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tl_set_fullscreen(self: Rc<Self>, fullscreen: bool) {
|
fn tl_set_fullscreen(self: Rc<Self>, fullscreen: bool) {
|
||||||
|
|
@ -193,7 +181,7 @@ pub struct FullscreenedData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ToplevelData {
|
pub struct ToplevelData {
|
||||||
pub active: Cell<bool>,
|
pub self_active: Cell<bool>,
|
||||||
pub client: Option<Rc<Client>>,
|
pub client: Option<Rc<Client>>,
|
||||||
pub state: Rc<State>,
|
pub state: Rc<State>,
|
||||||
pub active_surfaces: ThresholdCounter,
|
pub active_surfaces: ThresholdCounter,
|
||||||
|
|
@ -220,7 +208,7 @@ pub struct ToplevelData {
|
||||||
impl ToplevelData {
|
impl ToplevelData {
|
||||||
pub fn new(state: &Rc<State>, title: String, client: Option<Rc<Client>>) -> Self {
|
pub fn new(state: &Rc<State>, title: String, client: Option<Rc<Client>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
active: Cell::new(false),
|
self_active: Cell::new(false),
|
||||||
client,
|
client,
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
active_surfaces: Default::default(),
|
active_surfaces: Default::default(),
|
||||||
|
|
@ -245,7 +233,23 @@ impl ToplevelData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active(&self) -> bool {
|
pub fn active(&self) -> bool {
|
||||||
self.active_surfaces.active() || self.active.get()
|
self.active_surfaces.active() || self.self_active.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_active<T: ToplevelNode, F: FnOnce()>(&self, tl: &T, f: F) {
|
||||||
|
let active_old = self.active();
|
||||||
|
f();
|
||||||
|
let active_new = self.active();
|
||||||
|
if active_old != active_new {
|
||||||
|
tl.tl_set_active(active_new);
|
||||||
|
if let Some(parent) = self.parent.get() {
|
||||||
|
parent.node_child_active_changed(tl.tl_as_node(), active_new, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_self_active<T: ToplevelNode>(&self, node: &T, active: bool) {
|
||||||
|
self.update_active(node, || self.self_active.set(active));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float_size(&self, ws: &WorkspaceNode) -> (i32, i32) {
|
pub fn float_size(&self, ws: &WorkspaceNode) -> (i32, i32) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue