Merge pull request #446 from khyperia/more-config-methods
jay-config: add Seat.get_keyboard_output and Connector.workspaces
This commit is contained in:
commit
c7bba173fb
21 changed files with 191 additions and 36 deletions
|
|
@ -417,6 +417,12 @@ impl Client {
|
|||
workspace
|
||||
}
|
||||
|
||||
pub fn get_seat_keyboard_workspace(&self, seat: Seat) -> Workspace {
|
||||
let res = self.send_with_response(&ClientMessage::GetSeatKeyboardWorkspace { seat });
|
||||
get_response!(res, Workspace(0), GetSeatKeyboardWorkspace { workspace });
|
||||
workspace
|
||||
}
|
||||
|
||||
pub fn set_default_workspace_capture(&self, capture: bool) {
|
||||
self.send(&ClientMessage::SetDefaultWorkspaceCapture { capture });
|
||||
}
|
||||
|
|
@ -1076,6 +1082,19 @@ impl Client {
|
|||
self.send(&ClientMessage::SetEiSocketEnabled { enabled })
|
||||
}
|
||||
|
||||
pub fn get_connector_active_workspace(&self, connector: Connector) -> Workspace {
|
||||
let res =
|
||||
self.send_with_response(&ClientMessage::GetConnectorActiveWorkspace { connector });
|
||||
get_response!(res, Workspace(0), GetConnectorActiveWorkspace { workspace });
|
||||
workspace
|
||||
}
|
||||
|
||||
pub fn get_connector_workspaces(&self, connector: Connector) -> Vec<Workspace> {
|
||||
let res = self.send_with_response(&ClientMessage::GetConnectorWorkspaces { connector });
|
||||
get_response!(res, vec![], GetConnectorWorkspaces { workspaces });
|
||||
workspaces
|
||||
}
|
||||
|
||||
pub fn latch<F: FnOnce() + 'static>(&self, seat: Seat, f: F) {
|
||||
if !self.feat_mod_mask.get() {
|
||||
log::error!("compositor does not support latching");
|
||||
|
|
|
|||
|
|
@ -556,6 +556,15 @@ pub enum ClientMessage<'a> {
|
|||
SetShowFloatPinIcon {
|
||||
show: bool,
|
||||
},
|
||||
GetSeatKeyboardWorkspace {
|
||||
seat: Seat,
|
||||
},
|
||||
GetConnectorActiveWorkspace {
|
||||
connector: Connector,
|
||||
},
|
||||
GetConnectorWorkspaces {
|
||||
connector: Connector,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
@ -710,6 +719,15 @@ pub enum Response {
|
|||
GetFloatPinned {
|
||||
pinned: bool,
|
||||
},
|
||||
GetSeatKeyboardWorkspace {
|
||||
workspace: Workspace,
|
||||
},
|
||||
GetConnectorActiveWorkspace {
|
||||
workspace: Workspace,
|
||||
},
|
||||
GetConnectorWorkspaces {
|
||||
workspaces: Vec<Workspace>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
|
|||
|
|
@ -359,6 +359,14 @@ impl Seat {
|
|||
get!(Workspace(0)).get_seat_workspace(self)
|
||||
}
|
||||
|
||||
/// Returns the workspace that is currently active on the output that contains the seat's
|
||||
/// keyboard focus.
|
||||
///
|
||||
/// If no such workspace exists, `exists` returns `false` for the returned workspace.
|
||||
pub fn get_keyboard_workspace(self) -> Workspace {
|
||||
get!(Workspace(0)).get_seat_keyboard_workspace(self)
|
||||
}
|
||||
|
||||
/// Shows the workspace and sets the keyboard focus of the seat to that workspace.
|
||||
///
|
||||
/// If the workspace doesn't currently exist, it is created on the output that contains the
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use {
|
||||
crate::{
|
||||
_private::WireMode,
|
||||
PciId,
|
||||
PciId, Workspace,
|
||||
video::connector_type::{
|
||||
CON_9PIN_DIN, CON_COMPONENT, CON_COMPOSITE, CON_DISPLAY_PORT, CON_DPI, CON_DSI,
|
||||
CON_DVIA, CON_DVID, CON_DVII, CON_EDP, CON_EMBEDDED_WINDOW, CON_HDMIA, CON_HDMIB,
|
||||
|
|
@ -301,6 +301,21 @@ impl Connector {
|
|||
pub fn set_brightness(self, brightness: Option<f64>) {
|
||||
get!().connector_set_brightness(self, brightness);
|
||||
}
|
||||
|
||||
/// Get the currently visible/active workspace.
|
||||
///
|
||||
/// If this connector is not connected, or is there no active workspace, returns a
|
||||
/// workspace whose `exists()` returns false.
|
||||
pub fn active_workspace(self) -> Workspace {
|
||||
get!(Workspace(0)).get_connector_active_workspace(self)
|
||||
}
|
||||
|
||||
/// Get all workspaces on this connector.
|
||||
///
|
||||
/// If this connector is not connected, returns an empty list.
|
||||
pub fn workspaces(self) -> Vec<Workspace> {
|
||||
get!().get_connector_workspaces(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all available DRM devices.
|
||||
|
|
|
|||
|
|
@ -137,6 +137,20 @@ impl ConfigProxyHandler {
|
|||
self.next_id.fetch_add(1)
|
||||
}
|
||||
|
||||
fn get_workspace_by_name(&self, name: &String) -> Workspace {
|
||||
let id = match self.workspaces_by_name.get(name) {
|
||||
None => {
|
||||
let id = self.workspace_ids.fetch_add(1);
|
||||
let name = Rc::new(name.clone());
|
||||
self.workspaces_by_name.set(name.clone(), id);
|
||||
self.workspaces_by_id.set(id, name);
|
||||
id
|
||||
}
|
||||
Some(id) => id,
|
||||
};
|
||||
Workspace(id)
|
||||
}
|
||||
|
||||
fn handle_log_request(
|
||||
&self,
|
||||
level: LogLevel,
|
||||
|
|
@ -410,17 +424,7 @@ impl ConfigProxyHandler {
|
|||
fn handle_get_workspaces(&self) {
|
||||
let mut workspaces = vec![];
|
||||
for ws in self.state.workspaces.lock().values() {
|
||||
let id = match self.workspaces_by_name.get(&ws.name) {
|
||||
None => {
|
||||
let id = self.workspace_ids.fetch_add(1);
|
||||
let name = Rc::new(ws.name.clone());
|
||||
self.workspaces_by_name.set(name.clone(), id);
|
||||
self.workspaces_by_id.set(id, name);
|
||||
id
|
||||
}
|
||||
Some(id) => id,
|
||||
};
|
||||
workspaces.push(Workspace(id));
|
||||
workspaces.push(self.get_workspace_by_name(&ws.name));
|
||||
}
|
||||
self.respond(Response::GetWorkspaces { workspaces });
|
||||
}
|
||||
|
|
@ -708,18 +712,8 @@ impl ConfigProxyHandler {
|
|||
}
|
||||
|
||||
fn handle_get_workspace(&self, name: &str) {
|
||||
let name = Rc::new(name.to_owned());
|
||||
let ws = match self.workspaces_by_name.get(&name) {
|
||||
Some(w) => w,
|
||||
_ => {
|
||||
let ws = self.workspace_ids.fetch_add(1);
|
||||
self.workspaces_by_name.set(name.clone(), ws);
|
||||
self.workspaces_by_id.set(ws, name);
|
||||
ws
|
||||
}
|
||||
};
|
||||
self.respond(Response::GetWorkspace {
|
||||
workspace: Workspace(ws),
|
||||
workspace: self.get_workspace_by_name(&name.to_owned()),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -818,17 +812,27 @@ impl ConfigProxyHandler {
|
|||
fn handle_get_seat_workspace(&self, seat: Seat) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
let output = seat.get_output();
|
||||
let mut workspace = 0;
|
||||
let mut workspace = Workspace(0);
|
||||
if !output.is_dummy {
|
||||
if let Some(ws) = output.workspace.get() {
|
||||
if let Some(ws) = self.workspaces_by_name.get(&ws.name) {
|
||||
workspace = ws;
|
||||
workspace = self.get_workspace_by_name(&ws.name);
|
||||
}
|
||||
}
|
||||
self.respond(Response::GetSeatWorkspace { workspace });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_seat_keyboard_workspace(&self, seat: Seat) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
let mut workspace = Workspace(0);
|
||||
if let Some(output) = seat.get_keyboard_output() {
|
||||
if !output.is_dummy {
|
||||
if let Some(ws) = output.workspace.get() {
|
||||
workspace = self.get_workspace_by_name(&ws.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.respond(Response::GetSeatWorkspace {
|
||||
workspace: Workspace(workspace),
|
||||
});
|
||||
self.respond(Response::GetSeatKeyboardWorkspace { workspace });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -1292,6 +1296,27 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_connector_active_workspace(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let output = self.get_output_node(connector)?;
|
||||
let workspace = output
|
||||
.workspace
|
||||
.get()
|
||||
.map_or(Workspace(0), |ws| self.get_workspace_by_name(&ws.name));
|
||||
self.respond(Response::GetConnectorActiveWorkspace { workspace });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_connector_workspaces(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let output = self.get_output_node(connector)?;
|
||||
let workspaces = output
|
||||
.workspaces
|
||||
.iter()
|
||||
.map(|ws| self.get_workspace_by_name(&ws.name))
|
||||
.collect::<Vec<_>>();
|
||||
self.respond(Response::GetConnectorWorkspaces { workspaces });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_has_capability(&self, device: InputDevice, cap: Capability) -> Result<(), CphError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
let mut is_unknown = false;
|
||||
|
|
@ -1904,6 +1929,9 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::GetSeatWorkspace { seat } => self
|
||||
.handle_get_seat_workspace(seat)
|
||||
.wrn("get_seat_workspace")?,
|
||||
ClientMessage::GetSeatKeyboardWorkspace { seat } => self
|
||||
.handle_get_seat_keyboard_workspace(seat)
|
||||
.wrn("get_seat_keyboard_workspace")?,
|
||||
ClientMessage::SetDefaultWorkspaceCapture { capture } => {
|
||||
self.handle_set_default_workspace_capture(capture)
|
||||
}
|
||||
|
|
@ -2092,6 +2120,12 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::SetShowFloatPinIcon { show } => {
|
||||
self.handle_set_show_float_pin_icon(show)
|
||||
}
|
||||
ClientMessage::GetConnectorActiveWorkspace { connector } => self
|
||||
.handle_get_connector_active_workspace(connector)
|
||||
.wrn("get_connector_active_workspace")?,
|
||||
ClientMessage::GetConnectorWorkspaces { connector } => self
|
||||
.handle_get_connector_workspaces(connector)
|
||||
.wrn("get_connector_workspaces")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -401,6 +401,10 @@ impl WlSeatGlobal {
|
|||
self.cursor_user_group.latest_output()
|
||||
}
|
||||
|
||||
pub fn get_keyboard_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.keyboard_node.get().node_output()
|
||||
}
|
||||
|
||||
pub fn set_workspace(&self, ws: &Rc<WorkspaceNode>) {
|
||||
let tl = match self.keyboard_node.get().node_toplevel() {
|
||||
Some(tl) => tl,
|
||||
|
|
|
|||
|
|
@ -1783,6 +1783,10 @@ impl Node for WlSurface {
|
|||
self.buffer_abs_pos.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
Some(self.output.get())
|
||||
}
|
||||
|
||||
fn node_active_changed(&self, active: bool) {
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
tl.tl_surface_active_changed(active);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use {
|
|||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
rect::Rect,
|
||||
tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor},
|
||||
tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor, OutputNode},
|
||||
utils::numcell::NumCell,
|
||||
wire::{ExtSessionLockSurfaceV1Id, WlSurfaceId, ext_session_lock_surface_v1::*},
|
||||
},
|
||||
|
|
@ -123,6 +123,10 @@ impl Node for ExtSessionLockSurfaceV1 {
|
|||
self.surface.node_absolute_position()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.output.node()
|
||||
}
|
||||
|
||||
fn node_find_tree_at(
|
||||
&self,
|
||||
x: i32,
|
||||
|
|
|
|||
|
|
@ -292,6 +292,10 @@ impl<T: TrayItem> Node for T {
|
|||
self.data().surface.node_absolute_position()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.data().output.node()
|
||||
}
|
||||
|
||||
fn node_find_tree_at(
|
||||
&self,
|
||||
x: i32,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use {
|
|||
state::State,
|
||||
tree::{
|
||||
ContainerSplit, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId,
|
||||
NodeVisitor, StackedNode, TileDragDestination, ToplevelData, ToplevelNode,
|
||||
NodeVisitor, OutputNode, StackedNode, TileDragDestination, ToplevelData, ToplevelNode,
|
||||
ToplevelNodeBase, WorkspaceNode, default_tile_drag_destination,
|
||||
},
|
||||
utils::{clonecell::CloneCell, copyhashmap::CopyHashMap, linkedlist::LinkedNode},
|
||||
|
|
@ -346,6 +346,10 @@ impl Node for Xwindow {
|
|||
self.data.info.extents.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.toplevel_data.output_opt()
|
||||
}
|
||||
|
||||
fn node_do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _direction: Direction) {
|
||||
seat.focus_toplevel(self.clone());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,6 +314,10 @@ impl Node for XdgPopup {
|
|||
self.xdg.absolute_desired_extents.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.xdg.workspace.get().map(|w| w.output.get())
|
||||
}
|
||||
|
||||
fn node_find_tree_at(
|
||||
&self,
|
||||
x: i32,
|
||||
|
|
|
|||
|
|
@ -523,6 +523,10 @@ impl Node for XdgToplevel {
|
|||
self.xdg.absolute_desired_extents.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.toplevel_data.output_opt()
|
||||
}
|
||||
|
||||
fn node_do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _direction: Direction) {
|
||||
seat.focus_toplevel(self.clone());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -648,6 +648,10 @@ impl Node for ZwlrLayerSurfaceV1 {
|
|||
self.pos.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.output.node()
|
||||
}
|
||||
|
||||
fn node_find_tree_at(
|
||||
&self,
|
||||
x: i32,
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ pub trait Node: 'static {
|
|||
fn node_visit_children(&self, visitor: &mut dyn NodeVisitor);
|
||||
fn node_visible(&self) -> bool;
|
||||
fn node_absolute_position(&self) -> Rect;
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>>;
|
||||
|
||||
fn node_child_title_changed(self: Rc<Self>, child: &dyn Node, title: &str) {
|
||||
let _ = child;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use {
|
|||
text::TextTexture,
|
||||
tree::{
|
||||
ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId,
|
||||
TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase,
|
||||
OutputNode, TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase,
|
||||
WorkspaceNode, default_tile_drag_bounds, walker::NodeVisitor,
|
||||
},
|
||||
utils::{
|
||||
|
|
@ -1761,6 +1761,10 @@ impl Node for ContainerNode {
|
|||
fn node_is_container(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.toplevel_data.output_opt()
|
||||
}
|
||||
}
|
||||
|
||||
impl ContainingNode for ContainerNode {
|
||||
|
|
|
|||
|
|
@ -146,6 +146,10 @@ impl Node for DisplayNode {
|
|||
self.extents.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn node_find_tree_at(
|
||||
&self,
|
||||
x: i32,
|
||||
|
|
|
|||
|
|
@ -697,6 +697,10 @@ impl Node for FloatNode {
|
|||
self.position.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
Some(self.workspace.get().output.get())
|
||||
}
|
||||
|
||||
fn node_child_title_changed(self: Rc<Self>, _child: &dyn Node, title: &str) {
|
||||
self.update_child_title(title);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1343,6 +1343,10 @@ impl Node for OutputNode {
|
|||
self.global.pos.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.global.opt.node()
|
||||
}
|
||||
|
||||
fn node_do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
if self.state.lock.locked.get() {
|
||||
if let Some(lock) = self.lock_surface.get() {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ use {
|
|||
text::TextTexture,
|
||||
tree::{
|
||||
ContainerSplit, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId,
|
||||
NodeVisitor, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase,
|
||||
default_tile_drag_destination,
|
||||
NodeVisitor, OutputNode, TileDragDestination, ToplevelData, ToplevelNode,
|
||||
ToplevelNodeBase, default_tile_drag_destination,
|
||||
},
|
||||
utils::{
|
||||
asyncevent::AsyncEvent, errorfmt::ErrorFmt, on_drop_event::OnDropEvent,
|
||||
|
|
@ -201,6 +201,10 @@ impl Node for PlaceholderNode {
|
|||
fn node_into_toplevel(self: Rc<Self>) -> Option<Rc<dyn ToplevelNode>> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
self.toplevel.output_opt()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToplevelNodeBase for PlaceholderNode {
|
||||
|
|
|
|||
|
|
@ -600,12 +600,16 @@ impl ToplevelData {
|
|||
}
|
||||
|
||||
pub fn output(&self) -> Rc<OutputNode> {
|
||||
match self.workspace.get() {
|
||||
match self.output_opt() {
|
||||
None => self.state.dummy_output.get().unwrap(),
|
||||
Some(ws) => ws.output.get(),
|
||||
Some(o) => o,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn output_opt(&self) -> Option<Rc<OutputNode>> {
|
||||
self.workspace.get().map(|ws| ws.output.get())
|
||||
}
|
||||
|
||||
pub fn desired_pixel_size(&self) -> (i32, i32) {
|
||||
let (dw, dh) = self.desired_extents.get().size();
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
|
|
|
|||
|
|
@ -298,6 +298,10 @@ impl Node for WorkspaceNode {
|
|||
self.position.get()
|
||||
}
|
||||
|
||||
fn node_output(&self) -> Option<Rc<OutputNode>> {
|
||||
Some(self.output.get())
|
||||
}
|
||||
|
||||
fn node_do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
if let Some(fs) = self.fullscreen.get() {
|
||||
fs.node_do_focus(seat, direction);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue