autocommit 2022-04-17 17:59:45 CEST
This commit is contained in:
parent
a30306e3d5
commit
1eb0d3e173
21 changed files with 392 additions and 87 deletions
|
|
@ -12,10 +12,11 @@ use {
|
|||
keyboard::{
|
||||
mods::{Modifiers, ALT, CTRL, SHIFT},
|
||||
syms::{
|
||||
SYM_Super_L, SYM_b, SYM_c, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p,
|
||||
SYM_q, SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F13, SYM_F14,
|
||||
SYM_F15, SYM_F16, SYM_F17, SYM_F18, SYM_F19, SYM_F2, SYM_F20, SYM_F21, SYM_F22,
|
||||
SYM_F23, SYM_F24, SYM_F25, SYM_F3, SYM_F4, SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9,
|
||||
SYM_Super_L, SYM_a, SYM_b, SYM_c, SYM_d, SYM_e, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l,
|
||||
SYM_m, SYM_o, SYM_p, SYM_q, SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12,
|
||||
SYM_F13, SYM_F14, SYM_F15, SYM_F16, SYM_F17, SYM_F18, SYM_F19, SYM_F2, SYM_F20,
|
||||
SYM_F21, SYM_F22, SYM_F23, SYM_F24, SYM_F25, SYM_F3, SYM_F4, SYM_F5, SYM_F6,
|
||||
SYM_F7, SYM_F8, SYM_F9,
|
||||
},
|
||||
},
|
||||
quit, set_env,
|
||||
|
|
@ -27,7 +28,6 @@ use {
|
|||
},
|
||||
std::time::Duration,
|
||||
};
|
||||
use jay_config::keyboard::syms::{SYM_a, SYM_e, SYM_o};
|
||||
|
||||
const MOD: Modifiers = ALT;
|
||||
|
||||
|
|
@ -78,9 +78,15 @@ fn configure_seat(s: Seat) {
|
|||
s.bind(MOD | sym, move || s.show_workspace(ws));
|
||||
}
|
||||
|
||||
s.bind(MOD | SYM_a, || Command::new("spotify-remote").arg("a").spawn());
|
||||
s.bind(MOD | SYM_o, || Command::new("spotify-remote").arg("o").spawn());
|
||||
s.bind(MOD | SYM_e, || Command::new("spotify-remote").arg("e").spawn());
|
||||
s.bind(MOD | SYM_a, || {
|
||||
Command::new("spotify-remote").arg("a").spawn()
|
||||
});
|
||||
s.bind(MOD | SYM_o, || {
|
||||
Command::new("spotify-remote").arg("o").spawn()
|
||||
});
|
||||
s.bind(MOD | SYM_e, || {
|
||||
Command::new("spotify-remote").arg("e").spawn()
|
||||
});
|
||||
|
||||
fn do_grab(s: Seat, grab: bool) {
|
||||
for device in s.input_devices() {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
mod generate;
|
||||
mod idle;
|
||||
mod log;
|
||||
mod quit;
|
||||
mod screenshot;
|
||||
mod set_log_level;
|
||||
mod idle;
|
||||
|
||||
use {
|
||||
crate::compositor::start_compositor,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use crate::cli::{GlobalArgs, IdleArgs, IdleCmd, IdleSetArgs};
|
||||
use crate::tools::tool_client::{Handle, ToolClient};
|
||||
use crate::utils::errorfmt::ErrorFmt;
|
||||
use crate::wire::{jay_compositor, jay_idle, JayIdleId};
|
||||
use {
|
||||
crate::{
|
||||
cli::{GlobalArgs, IdleArgs, IdleCmd, IdleSetArgs},
|
||||
tools::tool_client::{Handle, ToolClient},
|
||||
utils::errorfmt::ErrorFmt,
|
||||
wire::{jay_compositor, jay_idle, JayIdleId},
|
||||
},
|
||||
std::{cell::Cell, collections::VecDeque, rc::Rc, str::FromStr},
|
||||
};
|
||||
|
||||
pub fn main(global: GlobalArgs, args: IdleArgs) {
|
||||
let tc = ToolClient::new(global.log_level.into());
|
||||
let idle = Idle {
|
||||
tc: tc.clone(),
|
||||
};
|
||||
let idle = Idle { tc: tc.clone() };
|
||||
tc.run(idle.run(args));
|
||||
}
|
||||
|
||||
|
|
@ -36,9 +35,7 @@ impl Idle {
|
|||
|
||||
async fn status(self, idle: JayIdleId) {
|
||||
let tc = &self.tc;
|
||||
tc.send(jay_idle::GetStatus {
|
||||
self_id: idle,
|
||||
});
|
||||
tc.send(jay_idle::GetStatus { self_id: idle });
|
||||
let interval = Rc::new(Cell::new(0u64));
|
||||
jay_idle::Interval::handle(tc, idle, interval.clone(), |iv, msg| {
|
||||
iv.set(msg.interval);
|
||||
|
|
@ -65,15 +62,25 @@ impl Idle {
|
|||
let mut pending_num = None;
|
||||
for comp in comp {
|
||||
match comp {
|
||||
Component::Number(_) if pending_num.is_some() => fatal!("missing number unit after {}", pending_num.unwrap()),
|
||||
Component::Number(_) if pending_num.is_some() => {
|
||||
fatal!("missing number unit after {}", pending_num.unwrap())
|
||||
}
|
||||
Component::Number(n) => pending_num = Some(n),
|
||||
|
||||
Component::Minutes(n) if pending_num.is_none() => fatal!("`{}` must be preceded by a number", n),
|
||||
Component::Minutes(_) if minutes.is_some() => fatal!("minutes specified multiple times"),
|
||||
Component::Minutes(n) if pending_num.is_none() => {
|
||||
fatal!("`{}` must be preceded by a number", n)
|
||||
}
|
||||
Component::Minutes(_) if minutes.is_some() => {
|
||||
fatal!("minutes specified multiple times")
|
||||
}
|
||||
Component::Minutes(_) => minutes = pending_num.take(),
|
||||
|
||||
Component::Seconds(n) if pending_num.is_none() => fatal!("`{}` must be preceded by a number", n),
|
||||
Component::Seconds(_) if seconds.is_some() => fatal!("seconds specified multiple times"),
|
||||
Component::Seconds(n) if pending_num.is_none() => {
|
||||
fatal!("`{}` must be preceded by a number", n)
|
||||
}
|
||||
Component::Seconds(_) if seconds.is_some() => {
|
||||
fatal!("seconds specified multiple times")
|
||||
}
|
||||
Component::Seconds(_) => seconds = pending_num.take(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ fn start_compositor2(
|
|||
change: Default::default(),
|
||||
timeout: Cell::new(Duration::from_secs(10 * 60)),
|
||||
timeout_changed: Default::default(),
|
||||
inhibitors: Default::default(),
|
||||
inhibitors_changed: Default::default(),
|
||||
},
|
||||
run_args,
|
||||
xwayland: XWaylandState {
|
||||
|
|
@ -149,6 +151,7 @@ fn start_compositor2(
|
|||
},
|
||||
socket_path: Default::default(),
|
||||
serial: Default::default(),
|
||||
idle_inhibitor_ids: Default::default(),
|
||||
});
|
||||
create_dummy_output(&state);
|
||||
let socket_path = Acceptor::install(&state)?;
|
||||
|
|
@ -176,6 +179,7 @@ async fn start_compositor3(state: Rc<State>) {
|
|||
}
|
||||
};
|
||||
state.backend.set(backend.clone());
|
||||
state.globals.add_singletons(&backend);
|
||||
|
||||
if backend.is_freestanding() {
|
||||
import_environment(&state, WAYLAND_DISPLAY, &state.socket_path.get());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::Backend,
|
||||
client::Client,
|
||||
ifs::{
|
||||
ipc::{
|
||||
|
|
@ -17,6 +18,7 @@ use {
|
|||
wl_subcompositor::WlSubcompositorGlobal,
|
||||
xdg_wm_base::XdgWmBaseGlobal,
|
||||
zwlr_layer_shell_v1::ZwlrLayerShellV1Global,
|
||||
zwp_idle_inhibit_manager_v1::ZwpIdleInhibitManagerV1Global,
|
||||
zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1Global,
|
||||
zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global,
|
||||
zxdg_output_manager_v1::ZxdgOutputManagerV1Global,
|
||||
|
|
@ -102,15 +104,18 @@ pub struct Globals {
|
|||
|
||||
impl Globals {
|
||||
pub fn new() -> Self {
|
||||
let slf = Self {
|
||||
Self {
|
||||
next_name: NumCell::new(1),
|
||||
registry: CopyHashMap::new(),
|
||||
outputs: Default::default(),
|
||||
seats: Default::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_singletons(&self, backend: &Rc<dyn Backend>) {
|
||||
macro_rules! add_singleton {
|
||||
($name:ident) => {
|
||||
slf.add_global_no_broadcast(&Rc::new($name::new(slf.name())));
|
||||
self.add_global_no_broadcast(&Rc::new($name::new(self.name())));
|
||||
};
|
||||
}
|
||||
add_singleton!(WlCompositorGlobal);
|
||||
|
|
@ -126,7 +131,10 @@ impl Globals {
|
|||
add_singleton!(ZwlrLayerShellV1Global);
|
||||
add_singleton!(ZxdgOutputManagerV1Global);
|
||||
add_singleton!(JayCompositorGlobal);
|
||||
slf
|
||||
|
||||
if backend.supports_idle() {
|
||||
add_singleton!(ZwpIdleInhibitManagerV1Global);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> GlobalName {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
pub mod ipc;
|
||||
pub mod jay_compositor;
|
||||
pub mod jay_idle;
|
||||
pub mod jay_log_file;
|
||||
pub mod jay_screenshot;
|
||||
pub mod org_kde_kwin_server_decoration;
|
||||
|
|
@ -20,10 +21,10 @@ pub mod wl_surface;
|
|||
pub mod xdg_positioner;
|
||||
pub mod xdg_wm_base;
|
||||
pub mod zwlr_layer_shell_v1;
|
||||
pub mod zwp_idle_inhibit_manager_v1;
|
||||
pub mod zwp_linux_buffer_params_v1;
|
||||
pub mod zwp_linux_dmabuf_v1;
|
||||
pub mod zxdg_decoration_manager_v1;
|
||||
pub mod zxdg_output_manager_v1;
|
||||
pub mod zxdg_output_v1;
|
||||
pub mod zxdg_toplevel_decoration_v1;
|
||||
pub mod jay_idle;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use {
|
|||
cli::CliLogLevel,
|
||||
client::{Client, ClientError},
|
||||
globals::{Global, GlobalName},
|
||||
ifs::{jay_log_file::JayLogFile, jay_screenshot::JayScreenshot},
|
||||
ifs::{jay_idle::JayIdle, jay_log_file::JayLogFile, jay_screenshot::JayScreenshot},
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
screenshoter::take_screenshot,
|
||||
|
|
@ -17,7 +17,6 @@ use {
|
|||
std::{ops::Deref, rc::Rc},
|
||||
thiserror::Error,
|
||||
};
|
||||
use crate::ifs::jay_idle::JayIdle;
|
||||
|
||||
pub struct JayCompositorGlobal {
|
||||
name: GlobalName,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
use std::time::Duration;
|
||||
use thiserror::Error;
|
||||
use {
|
||||
crate::{
|
||||
client::Client,
|
||||
client::{Client, ClientError},
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
wire::{jay_idle::*},
|
||||
utils::buffd::{MsgParser, MsgParserError},
|
||||
wire::{jay_idle::*, JayIdleId},
|
||||
},
|
||||
std::rc::Rc,
|
||||
std::{rc::Rc, time::Duration},
|
||||
thiserror::Error,
|
||||
};
|
||||
use crate::client::ClientError;
|
||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||
use crate::wire::JayIdleId;
|
||||
|
||||
pub struct JayIdle {
|
||||
pub id: JayIdleId,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,11 @@ impl WlCompositor {
|
|||
track!(self.client, surface);
|
||||
self.client.add_client_obj(&surface)?;
|
||||
if self.client.is_xwayland {
|
||||
self.client.state.xwayland.queue.push(XWaylandEvent::SurfaceCreated(surface.clone()));
|
||||
self.client
|
||||
.state
|
||||
.xwayland
|
||||
.queue
|
||||
.push(XWaylandEvent::SurfaceCreated(surface.clone()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use {
|
||||
crate::{ifs::wl_seat::WlSeatGlobal, tree::Node, utils::clonecell::CloneCell},
|
||||
crate::{
|
||||
ifs::wl_seat::WlSeatGlobal, tree::Node, utils::clonecell::CloneCell,
|
||||
xwayland::XWaylandEvent,
|
||||
},
|
||||
std::rc::Rc,
|
||||
};
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
|
||||
pub struct KbOwnerHolder {
|
||||
default: Rc<DefaultKbOwner>,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ pub mod wl_subsurface;
|
|||
pub mod xdg_surface;
|
||||
pub mod xwindow;
|
||||
pub mod zwlr_layer_surface_v1;
|
||||
pub mod zwp_idle_inhibitor_v1;
|
||||
|
||||
use {
|
||||
crate::{
|
||||
|
|
@ -46,6 +47,7 @@ use {
|
|||
rc::Rc,
|
||||
},
|
||||
thiserror::Error,
|
||||
zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
@ -103,6 +105,7 @@ pub struct WlSurface {
|
|||
cursors: SmallMap<SeatId, Rc<CursorSurface>, 1>,
|
||||
pub dnd_icons: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
pub tracker: Tracker<Self>,
|
||||
idle_inhibitor: CloneCell<Option<Rc<ZwpIdleInhibitorV1>>>,
|
||||
}
|
||||
|
||||
impl Debug for WlSurface {
|
||||
|
|
@ -200,25 +203,26 @@ impl WlSurface {
|
|||
id,
|
||||
node_id: client.state.node_ids.next(),
|
||||
client: client.clone(),
|
||||
visible: Cell::new(false),
|
||||
visible: Default::default(),
|
||||
role: Cell::new(SurfaceRole::None),
|
||||
pending: Default::default(),
|
||||
input_region: Cell::new(None),
|
||||
opaque_region: Cell::new(None),
|
||||
input_region: Default::default(),
|
||||
opaque_region: Default::default(),
|
||||
extents: Default::default(),
|
||||
buffer_abs_pos: Cell::new(Default::default()),
|
||||
need_extents_update: Cell::new(false),
|
||||
buffer: CloneCell::new(None),
|
||||
need_extents_update: Default::default(),
|
||||
buffer: Default::default(),
|
||||
buf_x: Default::default(),
|
||||
buf_y: Default::default(),
|
||||
children: Default::default(),
|
||||
ext: CloneCell::new(client.state.none_surface_ext.clone()),
|
||||
frame_requests: RefCell::new(vec![]),
|
||||
frame_requests: Default::default(),
|
||||
seat_state: Default::default(),
|
||||
toplevel: Default::default(),
|
||||
cursors: Default::default(),
|
||||
dnd_icons: Default::default(),
|
||||
tracker: Default::default(),
|
||||
idle_inhibitor: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +371,7 @@ impl WlSurface {
|
|||
self.unset_dnd_icons();
|
||||
self.unset_cursors();
|
||||
self.ext.get().on_surface_destroy()?;
|
||||
self.node_destroy(true);
|
||||
self.destroy_node(true);
|
||||
{
|
||||
let mut children = self.children.borrow_mut();
|
||||
if let Some(children) = &mut *children {
|
||||
|
|
@ -385,6 +389,7 @@ impl WlSurface {
|
|||
self.frame_requests.borrow_mut().clear();
|
||||
self.toplevel.set(None);
|
||||
self.client.remove_obj(self)?;
|
||||
self.idle_inhibitor.take();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -622,6 +627,7 @@ impl Object for WlSurface {
|
|||
mem::take(self.frame_requests.borrow_mut().deref_mut());
|
||||
self.buffer.set(None);
|
||||
self.toplevel.set(None);
|
||||
self.idle_inhibitor.take();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -638,6 +644,9 @@ impl SizedNode for WlSurface {
|
|||
}
|
||||
|
||||
fn destroy_node(&self, _detach: bool) {
|
||||
if let Some(inhibitor) = self.idle_inhibitor.get() {
|
||||
inhibitor.deactivate();
|
||||
}
|
||||
let children = self.children.borrow();
|
||||
if let Some(ch) = children.deref() {
|
||||
for ss in ch.subsurfaces.values() {
|
||||
|
|
@ -682,6 +691,13 @@ impl SizedNode for WlSurface {
|
|||
|
||||
fn set_visible(&self, visible: bool) {
|
||||
self.visible.set(visible);
|
||||
if let Some(inhibitor) = self.idle_inhibitor.get() {
|
||||
if visible {
|
||||
inhibitor.activate();
|
||||
} else {
|
||||
inhibitor.deactivate();
|
||||
}
|
||||
}
|
||||
let children = self.children.borrow_mut();
|
||||
if let Some(children) = children.deref() {
|
||||
for child in children.subsurfaces.values() {
|
||||
|
|
|
|||
|
|
@ -203,10 +203,7 @@ pub enum Change {
|
|||
}
|
||||
|
||||
impl Xwindow {
|
||||
pub fn new(
|
||||
data: &Rc<XwindowData>,
|
||||
surface: &Rc<WlSurface>,
|
||||
) -> Self {
|
||||
pub fn new(data: &Rc<XwindowData>, surface: &Rc<WlSurface>) -> Self {
|
||||
Self {
|
||||
id: data.state.node_ids.next(),
|
||||
seat_state: Default::default(),
|
||||
|
|
@ -323,7 +320,11 @@ impl SurfaceExt for Xwindow {
|
|||
self.surface.unset_ext();
|
||||
self.data.window.set(None);
|
||||
self.data.surface_id.set(None);
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::SurfaceDestroyed(self.surface.id));
|
||||
self.data
|
||||
.state
|
||||
.xwayland
|
||||
.queue
|
||||
.push(XWaylandEvent::SurfaceDestroyed(self.surface.id));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +390,11 @@ impl SizedNode for Xwindow {
|
|||
}
|
||||
|
||||
fn close(&self) {
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Close(self.data.clone()));
|
||||
self.data
|
||||
.state
|
||||
.xwayland
|
||||
.queue
|
||||
.push(XWaylandEvent::Close(self.data.clone()));
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
|
|
@ -427,7 +432,11 @@ impl SizedNode for Xwindow {
|
|||
let old = self.data.info.extents.replace(*rect);
|
||||
if old != *rect {
|
||||
if !self.data.info.override_redirect.get() {
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Configure(self.clone()));
|
||||
self.data
|
||||
.state
|
||||
.xwayland
|
||||
.queue
|
||||
.push(XWaylandEvent::Configure(self.clone()));
|
||||
}
|
||||
if old.position() != rect.position() {
|
||||
self.surface.set_absolute_position(rect.x1(), rect.y1());
|
||||
|
|
@ -482,7 +491,11 @@ impl ToplevelNode for Xwindow {
|
|||
}
|
||||
|
||||
fn activate(&self) {
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Activate(self.data.clone()));
|
||||
self.data
|
||||
.state
|
||||
.xwayland
|
||||
.queue
|
||||
.push(XWaylandEvent::Activate(self.data.clone()));
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>) {
|
||||
|
|
@ -503,7 +516,11 @@ impl ToplevelNode for Xwindow {
|
|||
}
|
||||
|
||||
fn close(&self) {
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Close(self.data.clone()));
|
||||
self.data
|
||||
.state
|
||||
.xwayland
|
||||
.queue
|
||||
.push(XWaylandEvent::Close(self.data.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
82
src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs
Normal file
82
src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
ifs::wl_surface::WlSurface,
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
utils::buffd::{MsgParser, MsgParserError},
|
||||
wire::{zwp_idle_inhibitor_v1::*, WlSurfaceId, ZwpIdleInhibitorV1Id},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
linear_ids!(IdleInhibitorIds, IdleInhibitorId, u64);
|
||||
|
||||
pub struct ZwpIdleInhibitorV1 {
|
||||
pub id: ZwpIdleInhibitorV1Id,
|
||||
pub inhibit_id: IdleInhibitorId,
|
||||
pub client: Rc<Client>,
|
||||
pub surface: Rc<WlSurface>,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
impl ZwpIdleInhibitorV1 {
|
||||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpIdleInhibitorV1Error> {
|
||||
let _req: Destroy = self.client.parse(self, parser)?;
|
||||
self.client.remove_obj(self)?;
|
||||
if self.surface.idle_inhibitor.take().is_some() {
|
||||
self.deactivate();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install(self: &Rc<Self>) -> Result<(), ZwpIdleInhibitorV1Error> {
|
||||
if self.surface.idle_inhibitor.get().is_some() {
|
||||
return Err(ZwpIdleInhibitorV1Error::MultipleInhibitors(self.surface.id));
|
||||
}
|
||||
self.surface.idle_inhibitor.set(Some(self.clone()));
|
||||
if self.surface.visible.get() {
|
||||
self.activate();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn activate(self: &Rc<Self>) {
|
||||
self.client.state.idle.add_inhibitor(self);
|
||||
}
|
||||
|
||||
pub fn deactivate(&self) {
|
||||
self.client.state.idle.remove_inhibitor(self);
|
||||
}
|
||||
}
|
||||
|
||||
object_base2! {
|
||||
ZwpIdleInhibitorV1;
|
||||
|
||||
DESTROY => destroy,
|
||||
}
|
||||
|
||||
impl Object for ZwpIdleInhibitorV1 {
|
||||
fn num_requests(&self) -> u32 {
|
||||
DESTROY + 1
|
||||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
self.deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_obj!(ZwpIdleInhibitorV1);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ZwpIdleInhibitorV1Error {
|
||||
#[error("Parsing failed")]
|
||||
MsgParserError(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("The surface {0} already has an inhibitor attached")]
|
||||
MultipleInhibitors(WlSurfaceId),
|
||||
}
|
||||
efrom!(ZwpIdleInhibitorV1Error, ClientError);
|
||||
efrom!(ZwpIdleInhibitorV1Error, MsgParserError);
|
||||
122
src/ifs/zwp_idle_inhibit_manager_v1.rs
Normal file
122
src/ifs/zwp_idle_inhibit_manager_v1.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
globals::{Global, GlobalName},
|
||||
ifs::{
|
||||
wl_surface::zwp_idle_inhibitor_v1::{ZwpIdleInhibitorV1, ZwpIdleInhibitorV1Error},
|
||||
zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Error,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
utils::buffd::{MsgParser, MsgParserError},
|
||||
wire::{zwp_idle_inhibit_manager_v1::*, ZwpIdleInhibitManagerV1Id},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct ZwpIdleInhibitManagerV1Global {
|
||||
name: GlobalName,
|
||||
}
|
||||
|
||||
impl ZwpIdleInhibitManagerV1Global {
|
||||
pub fn new(name: GlobalName) -> Self {
|
||||
Self { name }
|
||||
}
|
||||
|
||||
fn bind_(
|
||||
self: Rc<Self>,
|
||||
id: ZwpIdleInhibitManagerV1Id,
|
||||
client: &Rc<Client>,
|
||||
version: u32,
|
||||
) -> Result<(), ZxdgDecorationManagerV1Error> {
|
||||
let obj = Rc::new(ZwpIdleInhibitManagerV1 {
|
||||
id,
|
||||
client: client.clone(),
|
||||
_version: version,
|
||||
tracker: Default::default(),
|
||||
});
|
||||
track!(client, obj);
|
||||
client.add_client_obj(&obj)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
global_base!(
|
||||
ZwpIdleInhibitManagerV1Global,
|
||||
ZwpIdleInhibitManagerV1,
|
||||
ZwpIdleInhibitManagerV1Error
|
||||
);
|
||||
|
||||
impl Global for ZwpIdleInhibitManagerV1Global {
|
||||
fn singleton(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn version(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_global!(ZwpIdleInhibitManagerV1Global);
|
||||
|
||||
pub struct ZwpIdleInhibitManagerV1 {
|
||||
pub id: ZwpIdleInhibitManagerV1Id,
|
||||
pub client: Rc<Client>,
|
||||
pub _version: u32,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
impl ZwpIdleInhibitManagerV1 {
|
||||
pub fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpIdleInhibitManagerV1Error> {
|
||||
let _req: Destroy = self.client.parse(self, parser)?;
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_inhibitor(
|
||||
&self,
|
||||
parser: MsgParser<'_, '_>,
|
||||
) -> Result<(), ZwpIdleInhibitManagerV1Error> {
|
||||
let req: CreateInhibitor = self.client.parse(self, parser)?;
|
||||
let surface = self.client.lookup(req.surface)?;
|
||||
let inhibit = Rc::new(ZwpIdleInhibitorV1 {
|
||||
id: req.id,
|
||||
inhibit_id: self.client.state.idle_inhibitor_ids.next(),
|
||||
client: self.client.clone(),
|
||||
surface,
|
||||
tracker: Default::default(),
|
||||
});
|
||||
track!(self.client, inhibit);
|
||||
self.client.add_client_obj(&inhibit)?;
|
||||
inhibit.install()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base2! {
|
||||
ZwpIdleInhibitManagerV1;
|
||||
|
||||
DESTROY => destroy,
|
||||
CREATE_INHIBITOR => create_inhibitor,
|
||||
}
|
||||
|
||||
impl Object for ZwpIdleInhibitManagerV1 {
|
||||
fn num_requests(&self) -> u32 {
|
||||
CREATE_INHIBITOR + 1
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_obj!(ZwpIdleInhibitManagerV1);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ZwpIdleInhibitManagerV1Error {
|
||||
#[error("Parsing failed")]
|
||||
MsgParserError(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error(transparent)]
|
||||
ZwpIdleInhibitorV1Error(#[from] ZwpIdleInhibitorV1Error),
|
||||
}
|
||||
efrom!(ZwpIdleInhibitManagerV1Error, ClientError);
|
||||
efrom!(ZwpIdleInhibitManagerV1Error, MsgParserError);
|
||||
|
|
@ -180,8 +180,11 @@ macro_rules! id {
|
|||
|
||||
macro_rules! linear_ids {
|
||||
($ids:ident, $id:ident) => {
|
||||
linear_ids!($ids, $id, u32);
|
||||
};
|
||||
($ids:ident, $id:ident, $ty:ty) => {
|
||||
pub struct $ids {
|
||||
next: crate::utils::numcell::NumCell<u32>,
|
||||
next: crate::utils::numcell::NumCell<$ty>,
|
||||
}
|
||||
|
||||
impl Default for $ids {
|
||||
|
|
@ -199,16 +202,16 @@ macro_rules! linear_ids {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct $id(u32);
|
||||
pub struct $id($ty);
|
||||
|
||||
impl $id {
|
||||
#[allow(dead_code)]
|
||||
pub fn raw(&self) -> u32 {
|
||||
pub fn raw(&self) -> $ty {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn from_raw(id: u32) -> Self {
|
||||
pub fn from_raw(id: $ty) -> Self {
|
||||
Self(id)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
src/state.rs
23
src/state.rs
|
|
@ -15,7 +15,10 @@ use {
|
|||
globals::{Globals, GlobalsError, WaylandGlobal},
|
||||
ifs::{
|
||||
wl_seat::{SeatIds, WlSeatGlobal},
|
||||
wl_surface::NoneSurfaceExt,
|
||||
wl_surface::{
|
||||
zwp_idle_inhibitor_v1::{IdleInhibitorId, IdleInhibitorIds, ZwpIdleInhibitorV1},
|
||||
NoneSurfaceExt,
|
||||
},
|
||||
},
|
||||
logger::Logger,
|
||||
rect::Rect,
|
||||
|
|
@ -32,7 +35,7 @@ use {
|
|||
},
|
||||
wheel::Wheel,
|
||||
xkbcommon::{XkbContext, XkbKeymap},
|
||||
xwayland,
|
||||
xwayland::{self, XWaylandEvent},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
jay_config::Direction,
|
||||
|
|
@ -44,7 +47,6 @@ use {
|
|||
time::Duration,
|
||||
},
|
||||
};
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
|
||||
pub struct State {
|
||||
pub xkb_ctx: XkbContext,
|
||||
|
|
@ -60,6 +62,7 @@ pub struct State {
|
|||
pub globals: Globals,
|
||||
pub connector_ids: ConnectorIds,
|
||||
pub seat_ids: SeatIds,
|
||||
pub idle_inhibitor_ids: IdleInhibitorIds,
|
||||
pub input_device_ids: InputDeviceIds,
|
||||
pub node_ids: NodeIds,
|
||||
pub root: Rc<DisplayNode>,
|
||||
|
|
@ -101,6 +104,8 @@ pub struct IdleState {
|
|||
pub change: AsyncEvent,
|
||||
pub timeout: Cell<Duration>,
|
||||
pub timeout_changed: Cell<bool>,
|
||||
pub inhibitors: CopyHashMap<IdleInhibitorId, Rc<ZwpIdleInhibitorV1>>,
|
||||
pub inhibitors_changed: Cell<bool>,
|
||||
}
|
||||
|
||||
impl IdleState {
|
||||
|
|
@ -109,6 +114,18 @@ impl IdleState {
|
|||
self.timeout_changed.set(true);
|
||||
self.change.trigger();
|
||||
}
|
||||
|
||||
pub fn add_inhibitor(&self, inhibitor: &Rc<ZwpIdleInhibitorV1>) {
|
||||
self.inhibitors.set(inhibitor.inhibit_id, inhibitor.clone());
|
||||
self.inhibitors_changed.set(true);
|
||||
self.change.trigger();
|
||||
}
|
||||
|
||||
pub fn remove_inhibitor(&self, inhibitor: &ZwpIdleInhibitorV1) {
|
||||
self.inhibitors.remove(&inhibitor.inhibit_id);
|
||||
self.inhibitors_changed.set(true);
|
||||
self.change.trigger();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputDeviceData {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ pub async fn idle(state: Rc<State>, backend: Rc<dyn Backend>) {
|
|||
timer,
|
||||
idle: false,
|
||||
dead: false,
|
||||
is_inhibited: false,
|
||||
last_input: now(),
|
||||
};
|
||||
idle.run().await;
|
||||
|
|
@ -40,6 +41,7 @@ struct Idle {
|
|||
timer: Timer,
|
||||
idle: bool,
|
||||
dead: bool,
|
||||
is_inhibited: bool,
|
||||
last_input: c::timespec,
|
||||
}
|
||||
|
||||
|
|
@ -63,28 +65,43 @@ impl Idle {
|
|||
let timeout = self.state.idle.timeout.get();
|
||||
let since = duration_since(self.last_input);
|
||||
if since >= timeout {
|
||||
self.backend.set_idle(true);
|
||||
self.idle = true;
|
||||
if !timeout.is_zero() && !self.is_inhibited {
|
||||
self.backend.set_idle(true);
|
||||
self.idle = true;
|
||||
}
|
||||
} else {
|
||||
self.program_timer(timeout - since);
|
||||
self.program_timer2(timeout - since);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_idle_changes(&mut self) {
|
||||
if self.state.idle.inhibitors_changed.replace(false) {
|
||||
let is_inhibited = self.state.idle.inhibitors.len() > 0;
|
||||
if self.is_inhibited != is_inhibited {
|
||||
self.is_inhibited = is_inhibited;
|
||||
if !self.is_inhibited {
|
||||
self.program_timer();
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.state.idle.timeout_changed.replace(false) {
|
||||
self.program_timer(self.state.idle.timeout.get());
|
||||
self.program_timer();
|
||||
}
|
||||
if self.state.idle.input.replace(false) {
|
||||
self.last_input = now();
|
||||
if self.idle {
|
||||
self.backend.set_idle(false);
|
||||
self.idle = false;
|
||||
self.program_timer(self.state.idle.timeout.get());
|
||||
self.program_timer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn program_timer(&mut self, timeout: Duration) {
|
||||
fn program_timer(&mut self) {
|
||||
self.program_timer2(self.state.idle.timeout.get());
|
||||
}
|
||||
|
||||
fn program_timer2(&mut self, timeout: Duration) {
|
||||
if let Err(e) = self.timer.program(Some(timeout), None) {
|
||||
log::error!("Could not program idle timer: {}", ErrorFmt(e));
|
||||
self.dead = true;
|
||||
|
|
|
|||
|
|
@ -168,15 +168,9 @@ async fn run(
|
|||
Err(e) => return Err(XWaylandError::ExecFailed(e)),
|
||||
};
|
||||
let client_id = state.clients.id();
|
||||
let client = state.clients.spawn2(
|
||||
client_id,
|
||||
state,
|
||||
client1,
|
||||
9999,
|
||||
9999,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
let client = state
|
||||
.clients
|
||||
.spawn2(client_id, state, client1, 9999, 9999, true, true);
|
||||
let client = match client {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(XWaylandError::SpawnClient(e)),
|
||||
|
|
|
|||
|
|
@ -8,9 +8,7 @@ use {
|
|||
rect::Rect,
|
||||
state::State,
|
||||
tree::{Node, SizedNode},
|
||||
utils::{
|
||||
bitflags::BitflagsExt, errorfmt::ErrorFmt, linkedlist::LinkedList,
|
||||
},
|
||||
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, linkedlist::LinkedList},
|
||||
wire::WlSurfaceId,
|
||||
wire_xcon::{
|
||||
ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows,
|
||||
|
|
|
|||
8
wire/zwp_idle_inhibit_manager_v1.txt
Normal file
8
wire/zwp_idle_inhibit_manager_v1.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# requests
|
||||
|
||||
msg destroy = 0 { }
|
||||
|
||||
msg create_inhibitor = 1 {
|
||||
id: id(zwp_idle_inhibitor_v1),
|
||||
surface: id(wl_surface),
|
||||
}
|
||||
3
wire/zwp_idle_inhibitor_v1.txt
Normal file
3
wire/zwp_idle_inhibitor_v1.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# requests
|
||||
|
||||
msg destroy = 0 { }
|
||||
Loading…
Add table
Add a link
Reference in a new issue