autocommit 2022-04-02 00:31:30 CEST
This commit is contained in:
parent
2dd433aa04
commit
6ad6d83b7e
34 changed files with 446 additions and 161 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
use jay_config::embedded::grab_input_device;
|
use jay_config::embedded::grab_input_device;
|
||||||
use jay_config::input::{InputDevice, CAP_KEYBOARD, CAP_POINTER};
|
use jay_config::input::capability::{CAP_KEYBOARD, CAP_POINTER};
|
||||||
|
use jay_config::input::InputDevice;
|
||||||
use jay_config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT};
|
use jay_config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT};
|
||||||
use jay_config::keyboard::syms::{
|
use jay_config::keyboard::syms::{
|
||||||
SYM_Super_L, SYM_b, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p, SYM_q, SYM_t,
|
SYM_Super_L, SYM_b, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p, SYM_q, SYM_t,
|
||||||
|
|
@ -40,7 +41,7 @@ fn configure_seat(s: Seat) {
|
||||||
|
|
||||||
s.bind(SYM_Super_L, || Command::new("alacritty").spawn());
|
s.bind(SYM_Super_L, || Command::new("alacritty").spawn());
|
||||||
|
|
||||||
s.bind(MOD | SYM_p, || Command::new("xeyes").spawn());
|
s.bind(MOD | SYM_p, || Command::new("bemenu-run").spawn());
|
||||||
|
|
||||||
s.bind(MOD | SYM_q, quit);
|
s.bind(MOD | SYM_q, quit);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage};
|
use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage};
|
||||||
use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION};
|
use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION};
|
||||||
use crate::input::{AccelProfile, Capability, InputDevice};
|
use crate::input::acceleration::AccelProfile;
|
||||||
|
use crate::input::capability::Capability;
|
||||||
|
use crate::input::InputDevice;
|
||||||
use crate::keyboard::keymap::Keymap;
|
use crate::keyboard::keymap::Keymap;
|
||||||
use crate::theme::Color;
|
use crate::theme::Color;
|
||||||
use crate::{Axis, Command, Direction, LogLevel, ModifiedKeySym, Seat, Workspace};
|
use crate::{Axis, Command, Direction, LogLevel, ModifiedKeySym, Seat, Workspace};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::input::{AccelProfile, Capability, InputDevice};
|
use crate::input::acceleration::AccelProfile;
|
||||||
|
use crate::input::capability::Capability;
|
||||||
|
use crate::input::InputDevice;
|
||||||
use crate::keyboard::keymap::Keymap;
|
use crate::keyboard::keymap::Keymap;
|
||||||
use crate::keyboard::mods::Modifiers;
|
use crate::keyboard::mods::Modifiers;
|
||||||
use crate::keyboard::syms::KeySym;
|
use crate::keyboard::syms::KeySym;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
pub mod acceleration;
|
||||||
|
pub mod capability;
|
||||||
|
|
||||||
|
use crate::input::acceleration::AccelProfile;
|
||||||
|
use crate::input::capability::Capability;
|
||||||
use crate::Seat;
|
use crate::Seat;
|
||||||
use bincode::{Decode, Encode};
|
use bincode::{Decode, Encode};
|
||||||
|
|
||||||
|
|
@ -33,20 +38,3 @@ impl InputDevice {
|
||||||
get!(String::new()).device_name(self)
|
get!(String::new()).device_name(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
|
||||||
pub struct Capability(pub u32);
|
|
||||||
|
|
||||||
pub const CAP_KEYBOARD: Capability = Capability(0);
|
|
||||||
pub const CAP_POINTER: Capability = Capability(1);
|
|
||||||
pub const CAP_TOUCH: Capability = Capability(2);
|
|
||||||
pub const CAP_TABLET_TOOL: Capability = Capability(3);
|
|
||||||
pub const CAP_TABLET_PAD: Capability = Capability(4);
|
|
||||||
pub const CAP_GESTURE: Capability = Capability(5);
|
|
||||||
pub const CAP_SWITCH: Capability = Capability(6);
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
|
||||||
pub struct AccelProfile(pub u32);
|
|
||||||
|
|
||||||
pub const ACCEL_PROFILE_FLAT: AccelProfile = AccelProfile(1 << 0);
|
|
||||||
pub const ACCEL_PROFILE_ADAPTIVE: AccelProfile = AccelProfile(1 << 1);
|
|
||||||
|
|
|
||||||
7
jay-config/src/input/acceleration.rs
Normal file
7
jay-config/src/input/acceleration.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
use bincode::{Decode, Encode};
|
||||||
|
|
||||||
|
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
|
pub struct AccelProfile(pub u32);
|
||||||
|
|
||||||
|
pub const ACCEL_PROFILE_FLAT: AccelProfile = AccelProfile(1 << 0);
|
||||||
|
pub const ACCEL_PROFILE_ADAPTIVE: AccelProfile = AccelProfile(1 << 1);
|
||||||
12
jay-config/src/input/capability.rs
Normal file
12
jay-config/src/input/capability.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
use bincode::{Decode, Encode};
|
||||||
|
|
||||||
|
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
|
pub struct Capability(pub u32);
|
||||||
|
|
||||||
|
pub const CAP_KEYBOARD: Capability = Capability(0);
|
||||||
|
pub const CAP_POINTER: Capability = Capability(1);
|
||||||
|
pub const CAP_TOUCH: Capability = Capability(2);
|
||||||
|
pub const CAP_TABLET_TOOL: Capability = Capability(3);
|
||||||
|
pub const CAP_TABLET_PAD: Capability = Capability(4);
|
||||||
|
pub const CAP_GESTURE: Capability = Capability(5);
|
||||||
|
pub const CAP_SWITCH: Capability = Capability(6);
|
||||||
|
|
@ -3,9 +3,7 @@ mod monitor;
|
||||||
mod video;
|
mod video;
|
||||||
|
|
||||||
use crate::async_engine::{AsyncError, AsyncFd};
|
use crate::async_engine::{AsyncError, AsyncFd};
|
||||||
use crate::backend::{
|
use crate::backend::{Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState};
|
||||||
Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent,
|
|
||||||
};
|
|
||||||
use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice};
|
use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice};
|
||||||
use crate::dbus::DbusError;
|
use crate::dbus::DbusError;
|
||||||
use crate::drm::drm::DrmError;
|
use crate::drm::drm::DrmError;
|
||||||
|
|
@ -30,9 +28,11 @@ use crate::utils::syncqueue::SyncQueue;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::future::pending;
|
use std::future::pending;
|
||||||
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uapi::{c, OwnedFd};
|
use uapi::{c, OwnedFd};
|
||||||
|
use crate::utils::smallmap::SmallMap;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum MetalError {
|
pub enum MetalError {
|
||||||
|
|
@ -198,6 +198,10 @@ struct MetalInputDevice {
|
||||||
vscroll: Cell<f64>,
|
vscroll: Cell<f64>,
|
||||||
name: CloneCell<Rc<String>>,
|
name: CloneCell<Rc<String>>,
|
||||||
|
|
||||||
|
// state
|
||||||
|
pressed_keys: SmallMap<u32, (), 5>,
|
||||||
|
pressed_buttons: SmallMap<u32, (), 2>,
|
||||||
|
|
||||||
// config
|
// config
|
||||||
left_handed: Cell<Option<bool>>,
|
left_handed: Cell<Option<bool>>,
|
||||||
accel_profile: Cell<Option<AccelProfile>>,
|
accel_profile: Cell<Option<AccelProfile>>,
|
||||||
|
|
@ -205,6 +209,14 @@ struct MetalInputDevice {
|
||||||
transform_matrix: Cell<Option<[[f64; 2]; 2]>>,
|
transform_matrix: Cell<Option<[[f64; 2]; 2]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for MetalInputDevice {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Some(fd) = self.fd.take() {
|
||||||
|
mem::forget(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum MetalDevice {
|
enum MetalDevice {
|
||||||
Input(Rc<MetalInputDevice>),
|
Input(Rc<MetalInputDevice>),
|
||||||
|
|
@ -250,6 +262,15 @@ impl MetalInputDevice {
|
||||||
dev.device().set_accel_speed(speed);
|
dev.device().set_accel_speed(speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pre_pause(&self) {
|
||||||
|
for (key, _) in self.pressed_keys.take() {
|
||||||
|
self.event(InputEvent::Key(key, KeyState::Released));
|
||||||
|
}
|
||||||
|
for (button, _) in self.pressed_buttons.take() {
|
||||||
|
self.event(InputEvent::Button(button, KeyState::Released));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputDevice for MetalInputDevice {
|
impl InputDevice for MetalInputDevice {
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,14 @@ impl MetalBackend {
|
||||||
fn handle_keyboard_key(self: &Rc<Self>, event: LibInputEvent) {
|
fn handle_keyboard_key(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
let (event, dev) = unpack!(self, event, keyboard_event);
|
let (event, dev) = unpack!(self, event, keyboard_event);
|
||||||
let state = if event.key_state() == LIBINPUT_KEY_STATE_PRESSED {
|
let state = if event.key_state() == LIBINPUT_KEY_STATE_PRESSED {
|
||||||
|
if dev.pressed_keys.insert(event.key(), ()).is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
KeyState::Pressed
|
KeyState::Pressed
|
||||||
} else {
|
} else {
|
||||||
|
if dev.pressed_keys.remove(&event.key()).is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
KeyState::Released
|
KeyState::Released
|
||||||
};
|
};
|
||||||
dev.event(InputEvent::Key(event.key(), state));
|
dev.event(InputEvent::Key(event.key(), state));
|
||||||
|
|
@ -132,8 +138,14 @@ impl MetalBackend {
|
||||||
fn handle_pointer_button(self: &Rc<Self>, event: LibInputEvent) {
|
fn handle_pointer_button(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
let (event, dev) = unpack!(self, event, pointer_event);
|
let (event, dev) = unpack!(self, event, pointer_event);
|
||||||
let state = if event.button_state() == LIBINPUT_BUTTON_STATE_PRESSED {
|
let state = if event.button_state() == LIBINPUT_BUTTON_STATE_PRESSED {
|
||||||
|
if dev.pressed_buttons.insert(event.button(), ()).is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
KeyState::Pressed
|
KeyState::Pressed
|
||||||
} else {
|
} else {
|
||||||
|
if dev.pressed_buttons.remove(&event.button()).is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
KeyState::Released
|
KeyState::Released
|
||||||
};
|
};
|
||||||
dev.event(InputEvent::Button(event.button(), state));
|
dev.event(InputEvent::Button(event.button(), state));
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ impl MetalBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_input_device_removed(self: &Rc<Self>, dev: &Rc<MetalInputDevice>) {
|
fn handle_input_device_removed(self: &Rc<Self>, dev: &Rc<MetalInputDevice>) {
|
||||||
|
dev.pre_pause();
|
||||||
log::info!("Device removed: {}", dev.devnode.to_bytes().as_bstr());
|
log::info!("Device removed: {}", dev.devnode.to_bytes().as_bstr());
|
||||||
self.device_holder.input_devices.borrow_mut()[dev.slot] = None;
|
self.device_holder.input_devices.borrow_mut()[dev.slot] = None;
|
||||||
dev.fd.set(None);
|
dev.fd.set(None);
|
||||||
|
|
@ -148,6 +149,7 @@ impl MetalBackend {
|
||||||
|
|
||||||
fn handle_input_device_paused(self: &Rc<Self>, dev: &Rc<MetalInputDevice>) {
|
fn handle_input_device_paused(self: &Rc<Self>, dev: &Rc<MetalInputDevice>) {
|
||||||
log::info!("Device paused: {}", dev.devnode.to_bytes().as_bstr());
|
log::info!("Device paused: {}", dev.devnode.to_bytes().as_bstr());
|
||||||
|
dev.pre_pause();
|
||||||
if let Some(rd) = dev.inputdev.take() {
|
if let Some(rd) = dev.inputdev.take() {
|
||||||
rd.device().unset_slot();
|
rd.device().unset_slot();
|
||||||
}
|
}
|
||||||
|
|
@ -282,6 +284,8 @@ impl MetalBackend {
|
||||||
hscroll: Cell::new(0.0),
|
hscroll: Cell::new(0.0),
|
||||||
vscroll: Cell::new(0.0),
|
vscroll: Cell::new(0.0),
|
||||||
name: Default::default(),
|
name: Default::default(),
|
||||||
|
pressed_keys: Default::default(),
|
||||||
|
pressed_buttons: Default::default(),
|
||||||
left_handed: Default::default(),
|
left_handed: Default::default(),
|
||||||
accel_profile: Default::default(),
|
accel_profile: Default::default(),
|
||||||
accel_speed: Default::default(),
|
accel_speed: Default::default(),
|
||||||
|
|
|
||||||
11
src/cli.rs
11
src/cli.rs
|
|
@ -1,6 +1,7 @@
|
||||||
mod generate;
|
mod generate;
|
||||||
mod log;
|
mod log;
|
||||||
mod quit;
|
mod quit;
|
||||||
|
mod set_log_level;
|
||||||
|
|
||||||
use crate::compositor::start_compositor;
|
use crate::compositor::start_compositor;
|
||||||
use ::log::Level;
|
use ::log::Level;
|
||||||
|
|
@ -31,6 +32,8 @@ pub enum Cmd {
|
||||||
GenerateCompletion(GenerateArgs),
|
GenerateCompletion(GenerateArgs),
|
||||||
/// Open the log file.
|
/// Open the log file.
|
||||||
Log(LogArgs),
|
Log(LogArgs),
|
||||||
|
/// Sets the log level.
|
||||||
|
SetLogLevel(SetLogArgs),
|
||||||
/// Stop the compositor.
|
/// Stop the compositor.
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +64,13 @@ pub struct LogArgs {
|
||||||
pager_end: bool,
|
pager_end: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Debug)]
|
||||||
|
pub struct SetLogArgs {
|
||||||
|
/// The new log level.
|
||||||
|
#[clap(arg_enum)]
|
||||||
|
level: CliLogLevel,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(ArgEnum, Debug, Copy, Clone, Hash)]
|
#[derive(ArgEnum, Debug, Copy, Clone, Hash)]
|
||||||
pub enum CliBackend {
|
pub enum CliBackend {
|
||||||
X11,
|
X11,
|
||||||
|
|
@ -108,5 +118,6 @@ pub fn main() {
|
||||||
Cmd::GenerateCompletion(g) => generate::main(g),
|
Cmd::GenerateCompletion(g) => generate::main(g),
|
||||||
Cmd::Log(a) => log::main(cli.global, a),
|
Cmd::Log(a) => log::main(cli.global, a),
|
||||||
Cmd::Quit => quit::main(cli.global),
|
Cmd::Quit => quit::main(cli.global),
|
||||||
|
Cmd::SetLogLevel(a) => set_log_level::main(cli.global, a),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
src/cli/set_log_level.rs
Normal file
28
src/cli/set_log_level.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::cli::{GlobalArgs, SetLogArgs};
|
||||||
|
use crate::tools::tool_client::ToolClient;
|
||||||
|
use crate::wire::jay_compositor::SetLogLevel;
|
||||||
|
|
||||||
|
pub fn main(global: GlobalArgs, args: SetLogArgs) {
|
||||||
|
let tc = ToolClient::new(global.log_level.into());
|
||||||
|
let logger = Rc::new(Log {
|
||||||
|
tc: tc.clone(),
|
||||||
|
args,
|
||||||
|
});
|
||||||
|
tc.run(run(logger));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Log {
|
||||||
|
tc: Rc<ToolClient>,
|
||||||
|
args: SetLogArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(log: Rc<Log>) {
|
||||||
|
let tc = &log.tc;
|
||||||
|
let comp = tc.jay_compositor().await;
|
||||||
|
tc.send(SetLogLevel {
|
||||||
|
self_id: comp,
|
||||||
|
level: log.args.level as u32,
|
||||||
|
});
|
||||||
|
tc.round_trip().await;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::acceptor::{Acceptor, AcceptorError};
|
use crate::acceptor::{Acceptor, AcceptorError};
|
||||||
use crate::async_engine::{AsyncEngine, AsyncError, Phase};
|
use crate::async_engine::{AsyncEngine, AsyncError, Phase};
|
||||||
|
use crate::backends::dummy::DummyOutput;
|
||||||
use crate::cli::{GlobalArgs, RunArgs};
|
use crate::cli::{GlobalArgs, RunArgs};
|
||||||
use crate::client::Clients;
|
use crate::client::Clients;
|
||||||
use crate::clientmem::ClientMemError;
|
use crate::clientmem::ClientMemError;
|
||||||
|
|
@ -8,12 +9,17 @@ use crate::dbus::Dbus;
|
||||||
use crate::event_loop::{EventLoop, EventLoopError};
|
use crate::event_loop::{EventLoop, EventLoopError};
|
||||||
use crate::forker::ForkerError;
|
use crate::forker::ForkerError;
|
||||||
use crate::globals::Globals;
|
use crate::globals::Globals;
|
||||||
|
use crate::ifs::wl_output::WlOutputGlobal;
|
||||||
use crate::ifs::wl_surface::NoneSurfaceExt;
|
use crate::ifs::wl_surface::NoneSurfaceExt;
|
||||||
use crate::logger::Logger;
|
use crate::logger::Logger;
|
||||||
use crate::render::RenderError;
|
use crate::render::RenderError;
|
||||||
use crate::sighand::SighandError;
|
use crate::sighand::SighandError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use crate::tree::{container_layout, container_render_data, float_layout, float_titles, DisplayNode, NodeIds, OutputNode, WorkspaceNode};
|
use crate::tree::{
|
||||||
|
container_layout, container_render_data, float_layout, float_titles, DisplayNode, NodeIds,
|
||||||
|
OutputNode, WorkspaceNode,
|
||||||
|
};
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
use crate::utils::errorfmt::ErrorFmt;
|
use crate::utils::errorfmt::ErrorFmt;
|
||||||
use crate::utils::fdcloser::FdCloser;
|
use crate::utils::fdcloser::FdCloser;
|
||||||
use crate::utils::numcell::NumCell;
|
use crate::utils::numcell::NumCell;
|
||||||
|
|
@ -23,14 +29,11 @@ use crate::wheel::{Wheel, WheelError};
|
||||||
use crate::xkbcommon::XkbContext;
|
use crate::xkbcommon::XkbContext;
|
||||||
use crate::{clientmem, forker, leaks, render, sighand, tasks, xwayland};
|
use crate::{clientmem, forker, leaks, render, sighand, tasks, xwayland};
|
||||||
use forker::ForkerProxy;
|
use forker::ForkerProxy;
|
||||||
use std::cell::{Cell};
|
use std::cell::Cell;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crate::backends::dummy::DummyOutput;
|
|
||||||
use crate::ifs::wl_output::WlOutputGlobal;
|
|
||||||
use crate::utils::clonecell::CloneCell;
|
|
||||||
|
|
||||||
pub fn start_compositor(global: GlobalArgs, args: RunArgs) {
|
pub fn start_compositor(global: GlobalArgs, args: RunArgs) {
|
||||||
let logger = Logger::install_compositor(global.log_level.into());
|
let logger = Logger::install_compositor(global.log_level.into());
|
||||||
|
|
@ -118,9 +121,12 @@ fn main_(logger: Arc<Logger>, _args: &RunArgs) -> Result<(), MainError> {
|
||||||
let dummy_output = Rc::new(OutputNode {
|
let dummy_output = Rc::new(OutputNode {
|
||||||
id: state.node_ids.next(),
|
id: state.node_ids.next(),
|
||||||
position: Default::default(),
|
position: Default::default(),
|
||||||
global: Rc::new(WlOutputGlobal::new(state.globals.name(), Rc::new(DummyOutput {
|
global: Rc::new(WlOutputGlobal::new(
|
||||||
id: state.output_ids.next(),
|
state.globals.name(),
|
||||||
}))),
|
Rc::new(DummyOutput {
|
||||||
|
id: state.output_ids.next(),
|
||||||
|
}),
|
||||||
|
)),
|
||||||
workspaces: Default::default(),
|
workspaces: Default::default(),
|
||||||
workspace: Default::default(),
|
workspace: Default::default(),
|
||||||
seat_state: Default::default(),
|
seat_state: Default::default(),
|
||||||
|
|
@ -132,13 +138,17 @@ fn main_(logger: Arc<Logger>, _args: &RunArgs) -> Result<(), MainError> {
|
||||||
let dummy_workspace = Rc::new(WorkspaceNode {
|
let dummy_workspace = Rc::new(WorkspaceNode {
|
||||||
id: state.node_ids.next(),
|
id: state.node_ids.next(),
|
||||||
output: CloneCell::new(dummy_output.clone()),
|
output: CloneCell::new(dummy_output.clone()),
|
||||||
|
position: Default::default(),
|
||||||
container: Default::default(),
|
container: Default::default(),
|
||||||
stacked: Default::default(),
|
stacked: Default::default(),
|
||||||
seat_state: Default::default(),
|
seat_state: Default::default(),
|
||||||
name: "dummy".to_string()
|
name: "dummy".to_string(),
|
||||||
|
output_link: Default::default(),
|
||||||
});
|
});
|
||||||
dummy_output.workspace.set(Some(dummy_workspace.clone()));
|
dummy_workspace.output_link.set(Some(
|
||||||
dummy_output.workspaces.borrow_mut().push(dummy_workspace);
|
dummy_output.workspaces.add_last(dummy_workspace.clone()),
|
||||||
|
));
|
||||||
|
dummy_output.show_workspace(&dummy_workspace);
|
||||||
state.dummy_output.set(Some(dummy_output));
|
state.dummy_output.set(Some(dummy_output));
|
||||||
}
|
}
|
||||||
forker.install(&state);
|
forker.install(&state);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::backend::{InputDeviceAccelProfile, InputDeviceCapability, InputDevice
|
||||||
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
|
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
|
||||||
use crate::state::{DeviceHandlerData, State};
|
use crate::state::{DeviceHandlerData, State};
|
||||||
use crate::tree::walker::NodeVisitorBase;
|
use crate::tree::walker::NodeVisitorBase;
|
||||||
use crate::tree::{ContainerNode, ContainerSplit, FloatNode, Node, WorkspaceNode};
|
use crate::tree::{ContainerNode, ContainerSplit, FloatNode, Node};
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
use crate::utils::copyhashmap::CopyHashMap;
|
||||||
use crate::utils::debug_fn::debug_fn;
|
use crate::utils::debug_fn::debug_fn;
|
||||||
use crate::utils::errorfmt::ErrorFmt;
|
use crate::utils::errorfmt::ErrorFmt;
|
||||||
|
|
@ -13,9 +13,13 @@ use crate::xkbcommon::XkbKeymap;
|
||||||
use bincode::error::DecodeError;
|
use bincode::error::DecodeError;
|
||||||
use jay_config::_private::bincode_ops;
|
use jay_config::_private::bincode_ops;
|
||||||
use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage};
|
use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage};
|
||||||
|
use jay_config::input::acceleration::{AccelProfile, ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT};
|
||||||
|
use jay_config::input::capability::{
|
||||||
|
Capability, CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD,
|
||||||
|
CAP_TABLET_TOOL, CAP_TOUCH,
|
||||||
|
};
|
||||||
use jay_config::input::{
|
use jay_config::input::{
|
||||||
AccelProfile, Capability, InputDevice, ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT, CAP_GESTURE,
|
InputDevice,
|
||||||
CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD, CAP_TABLET_TOOL, CAP_TOUCH,
|
|
||||||
};
|
};
|
||||||
use jay_config::keyboard::keymap::Keymap;
|
use jay_config::keyboard::keymap::Keymap;
|
||||||
use jay_config::keyboard::mods::Modifiers;
|
use jay_config::keyboard::mods::Modifiers;
|
||||||
|
|
@ -26,7 +30,6 @@ use log::Level;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crate::utils::clonecell::CloneCell;
|
|
||||||
|
|
||||||
pub(super) struct ConfigProxyHandler {
|
pub(super) struct ConfigProxyHandler {
|
||||||
pub client_data: Cell<*const u8>,
|
pub client_data: Cell<*const u8>,
|
||||||
|
|
@ -163,7 +166,7 @@ impl ConfigProxyHandler {
|
||||||
fn get_workspace(&self, ws: Workspace) -> Result<Rc<String>, CphError> {
|
fn get_workspace(&self, ws: Workspace) -> Result<Rc<String>, CphError> {
|
||||||
match self.workspaces_by_id.get(&ws.0) {
|
match self.workspaces_by_id.get(&ws.0) {
|
||||||
Some(ws) => Ok(ws),
|
Some(ws) => Ok(ws),
|
||||||
_ => Err(CphError::WorkspaceDoesNotExist(ws))
|
_ => Err(CphError::WorkspaceDoesNotExist(ws)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,33 +286,7 @@ impl ConfigProxyHandler {
|
||||||
fn handle_show_workspace(&self, seat: Seat, ws: Workspace) -> Result<(), ShowWorkspaceError> {
|
fn handle_show_workspace(&self, seat: Seat, ws: Workspace) -> Result<(), ShowWorkspaceError> {
|
||||||
let seat = self.get_seat(seat)?;
|
let seat = self.get_seat(seat)?;
|
||||||
let name = self.get_workspace(ws)?;
|
let name = self.get_workspace(ws)?;
|
||||||
let output = match self.state.workspaces.get(name.as_str()) {
|
self.state.show_workspace(&seat, &name);
|
||||||
Some(ws) => {
|
|
||||||
let output = ws.output.get();
|
|
||||||
output.workspace.set(Some(ws.clone()));
|
|
||||||
output
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let output = seat.get_output();
|
|
||||||
if output.is_dummy {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let ws = Rc::new(WorkspaceNode {
|
|
||||||
id: self.state.node_ids.next(),
|
|
||||||
output: CloneCell::new(output.clone()),
|
|
||||||
container: Default::default(),
|
|
||||||
stacked: Default::default(),
|
|
||||||
seat_state: Default::default(),
|
|
||||||
name: name.to_string(),
|
|
||||||
});
|
|
||||||
output.workspaces.borrow_mut().push(ws.clone());
|
|
||||||
output.workspace.set(Some(ws.clone()));
|
|
||||||
self.state.workspaces.set(name.to_string(), ws);
|
|
||||||
output
|
|
||||||
}
|
|
||||||
};
|
|
||||||
output.update_render_data();
|
|
||||||
self.state.tree_changed();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -653,7 +630,9 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
ClientMessage::GetDeviceName { device } => self.handle_get_device_name(device)?,
|
ClientMessage::GetDeviceName { device } => self.handle_get_device_name(device)?,
|
||||||
ClientMessage::GetWorkspace { name } => self.handle_get_workspace(name),
|
ClientMessage::GetWorkspace { name } => self.handle_get_workspace(name),
|
||||||
ClientMessage::ShowWorkspace { seat, workspace } => self.handle_show_workspace(seat, workspace)?,
|
ClientMessage::ShowWorkspace { seat, workspace } => {
|
||||||
|
self.handle_show_workspace(seat, workspace)?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||||
use crate::wire::jay_compositor::*;
|
use crate::wire::jay_compositor::*;
|
||||||
use crate::wire::JayCompositorId;
|
use crate::wire::JayCompositorId;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use log::Level;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::cli::CliLogLevel;
|
||||||
|
|
||||||
pub struct JayCompositorGlobal {
|
pub struct JayCompositorGlobal {
|
||||||
name: GlobalName,
|
name: GlobalName,
|
||||||
|
|
@ -81,6 +83,25 @@ impl JayCompositor {
|
||||||
self.client.state.el.stop();
|
self.client.state.el.stop();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_log_level(&self, parser: MsgParser<'_, '_>) -> Result<(), SetLogLevelError> {
|
||||||
|
let req: SetLogLevel = self.client.parse(self, parser)?;
|
||||||
|
const ERROR: u32 = CliLogLevel::Error as u32;
|
||||||
|
const WARN: u32 = CliLogLevel::Warn as u32;
|
||||||
|
const INFO: u32 = CliLogLevel::Info as u32;
|
||||||
|
const DEBUG: u32 = CliLogLevel::Debug as u32;
|
||||||
|
const TRACE: u32 = CliLogLevel::Trace as u32;
|
||||||
|
let level = match req.level {
|
||||||
|
ERROR => Level::Error,
|
||||||
|
WARN => Level::Warn,
|
||||||
|
INFO => Level::Info,
|
||||||
|
DEBUG => Level::Debug,
|
||||||
|
TRACE => Level::Trace,
|
||||||
|
_ => return Err(SetLogLevelError::UnknownLogLevel(req.level)),
|
||||||
|
};
|
||||||
|
self.client.state.logger.set_level(level);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_base! {
|
object_base! {
|
||||||
|
|
@ -89,11 +110,12 @@ object_base! {
|
||||||
DESTROY => destroy,
|
DESTROY => destroy,
|
||||||
GET_LOG_FILE => get_log_file,
|
GET_LOG_FILE => get_log_file,
|
||||||
QUIT => quit,
|
QUIT => quit,
|
||||||
|
SET_LOG_LEVEL => set_log_level,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for JayCompositor {
|
impl Object for JayCompositor {
|
||||||
fn num_requests(&self) -> u32 {
|
fn num_requests(&self) -> u32 {
|
||||||
QUIT + 1
|
SET_LOG_LEVEL + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,6 +129,8 @@ pub enum JayCompositorError {
|
||||||
GetLogFileError(#[from] GetLogFileError),
|
GetLogFileError(#[from] GetLogFileError),
|
||||||
#[error("Could not process a `quit` request")]
|
#[error("Could not process a `quit` request")]
|
||||||
QuitError(#[from] QuitError),
|
QuitError(#[from] QuitError),
|
||||||
|
#[error("Could not process a `set_log_level` request")]
|
||||||
|
SetLogLevelError(#[from] SetLogLevelError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ClientError(Box<ClientError>),
|
ClientError(Box<ClientError>),
|
||||||
}
|
}
|
||||||
|
|
@ -138,3 +162,12 @@ pub enum QuitError {
|
||||||
MsgParserError(#[source] Box<MsgParserError>),
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
}
|
}
|
||||||
efrom!(QuitError, MsgParserError);
|
efrom!(QuitError, MsgParserError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetLogLevelError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error("Unknown log level {0}")]
|
||||||
|
UnknownLogLevel(u32),
|
||||||
|
}
|
||||||
|
efrom!(SetLogLevelError, MsgParserError);
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ use jay_config::Direction;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{DerefMut};
|
use std::ops::DerefMut;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uapi::{c, Errno, OwnedFd};
|
use uapi::{c, Errno, OwnedFd};
|
||||||
|
|
@ -373,6 +373,10 @@ impl WlSeatGlobal {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn workspace_changed(self: &Rc<Self>, output: &Rc<OutputNode>) {
|
||||||
|
self.kb_owner.workspace_changed(self, output);
|
||||||
|
}
|
||||||
|
|
||||||
fn bind_(
|
fn bind_(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
id: WlSeatId,
|
id: WlSeatId,
|
||||||
|
|
|
||||||
|
|
@ -192,8 +192,14 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_tiled_keyboard_toplevel(&self, new: &dyn Node) -> Option<Rc<dyn ToplevelNode>> {
|
pub fn last_tiled_keyboard_toplevel(&self, new: &dyn Node) -> Option<Rc<dyn ToplevelNode>> {
|
||||||
|
let output = self.output.get();
|
||||||
|
let workspace = output.workspace.get().unwrap();
|
||||||
let is_container = new.is_container();
|
let is_container = new.is_container();
|
||||||
for tl in self.toplevel_focus_history.rev_iter() {
|
for tl in self.toplevel_focus_history.rev_iter() {
|
||||||
|
match tl.as_node().get_workspace() {
|
||||||
|
Some(ws) if ws.id == workspace.id => { },
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
let parent_is_float = match tl.parent() {
|
let parent_is_float = match tl.parent() {
|
||||||
Some(pn) => pn.is_float(),
|
Some(pn) => pn.is_float(),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
use std::ops::Deref;
|
||||||
use crate::ifs::wl_seat::WlSeatGlobal;
|
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||||
use crate::tree::Node;
|
use crate::tree::{Node, OutputNode};
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
|
@ -29,6 +30,10 @@ impl KbOwnerHolder {
|
||||||
pub fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) {
|
pub fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) {
|
||||||
self.owner.get().set_kb_node(seat, node);
|
self.owner.get().set_kb_node(seat, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn workspace_changed(&self, seat: &Rc<WlSeatGlobal>, output: &Rc<OutputNode>) {
|
||||||
|
self.owner.get().workspace_changed(seat, output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DefaultKbOwner;
|
struct DefaultKbOwner;
|
||||||
|
|
@ -39,6 +44,7 @@ trait KbOwner {
|
||||||
fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool;
|
fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool;
|
||||||
fn ungrab(&self, seat: &Rc<WlSeatGlobal>);
|
fn ungrab(&self, seat: &Rc<WlSeatGlobal>);
|
||||||
fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>);
|
fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>);
|
||||||
|
fn workspace_changed(&self, seat: &Rc<WlSeatGlobal>, output: &Rc<OutputNode>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KbOwner for DefaultKbOwner {
|
impl KbOwner for DefaultKbOwner {
|
||||||
|
|
@ -68,6 +74,31 @@ impl KbOwner for DefaultKbOwner {
|
||||||
node.clone().focus(seat);
|
node.clone().focus(seat);
|
||||||
seat.keyboard_node.set(node.clone());
|
seat.keyboard_node.set(node.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn workspace_changed(&self, seat: &Rc<WlSeatGlobal>, output: &Rc<OutputNode>) {
|
||||||
|
let new_ws = match output.workspace.get() {
|
||||||
|
Some(ws) => ws,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
let node = seat.keyboard_node.get();
|
||||||
|
let ws = match node.get_workspace() {
|
||||||
|
None => return,
|
||||||
|
Some(ws) => ws,
|
||||||
|
};
|
||||||
|
let ws_output = ws.output.get();
|
||||||
|
if ws_output.id != output.id {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for tl in seat.toplevel_focus_history.rev_iter() {
|
||||||
|
if let Some(tl_ws) = tl.as_node().get_workspace() {
|
||||||
|
if tl_ws.id == new_ws.id {
|
||||||
|
self.set_kb_node(seat, tl.deref().clone().into_node());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.set_kb_node(seat, seat.state.root.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KbOwner for GrabKbOwner {
|
impl KbOwner for GrabKbOwner {
|
||||||
|
|
@ -82,4 +113,8 @@ impl KbOwner for GrabKbOwner {
|
||||||
fn set_kb_node(&self, _seat: &Rc<WlSeatGlobal>, _node: Rc<dyn Node>) {
|
fn set_kb_node(&self, _seat: &Rc<WlSeatGlobal>, _node: Rc<dyn Node>) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn workspace_changed(&self, _seat: &Rc<WlSeatGlobal>, _output: &Rc<OutputNode>) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::rect::Rect;
|
||||||
use crate::render::Renderer;
|
use crate::render::Renderer;
|
||||||
use crate::tree::toplevel::ToplevelNode;
|
use crate::tree::toplevel::ToplevelNode;
|
||||||
use crate::tree::walker::NodeVisitor;
|
use crate::tree::walker::NodeVisitor;
|
||||||
use crate::tree::{ContainerNode, ContainerSplit, Node, NodeId};
|
use crate::tree::{ContainerNode, ContainerSplit, Node, NodeId, WorkspaceNode};
|
||||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
use crate::utils::linkedlist::LinkedList;
|
use crate::utils::linkedlist::LinkedList;
|
||||||
|
|
@ -643,6 +643,13 @@ impl Node for WlSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
if let Some(tl) = self.toplevel.get() {
|
||||||
|
return tl.as_node().get_workspace();
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn get_parent_mono(&self) -> Option<bool> {
|
fn get_parent_mono(&self) -> Option<bool> {
|
||||||
self.toplevel
|
self.toplevel
|
||||||
.get()
|
.get()
|
||||||
|
|
@ -679,7 +686,7 @@ impl Node for WlSurface {
|
||||||
Some(tl) => tl,
|
Some(tl) => tl,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let ws = match tl.workspace() {
|
let ws = match tl.as_node().get_workspace() {
|
||||||
Some(ws) => ws,
|
Some(ws) => ws,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,10 @@ impl SurfaceExt for WlSubsurface {
|
||||||
fn into_subsurface(self: Rc<Self>) -> Option<Rc<WlSubsurface>> {
|
fn into_subsurface(self: Rc<Self>) -> Option<Rc<WlSubsurface>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn accepts_kb_focus(&self) -> bool {
|
||||||
|
self.parent.accepts_kb_focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
|
|
@ -356,6 +356,10 @@ impl SurfaceExt for XdgSurface {
|
||||||
fn extents_changed(&self) {
|
fn extents_changed(&self) {
|
||||||
self.update_extents();
|
self.update_extents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn accepts_kb_focus(&self) -> bool {
|
||||||
|
self.role.get() == XdgSurfaceRole::XdgToplevel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::client::{Client, ClientError};
|
use crate::client::{Client, ClientError};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
use crate::ifs::wl_seat::{ NodeSeatState, WlSeatGlobal};
|
||||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceExt};
|
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceExt};
|
||||||
use crate::ifs::xdg_positioner::{XdgPositioned, XdgPositioner, CA};
|
use crate::ifs::xdg_positioner::{XdgPositioned, XdgPositioner, CA};
|
||||||
use crate::leaks::Tracker;
|
use crate::leaks::Tracker;
|
||||||
|
|
@ -281,6 +281,10 @@ impl Node for XdgPopup {
|
||||||
visitor.visit_surface(&self.xdg.surface);
|
visitor.visit_surface(&self.xdg.surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
self.xdg.workspace.get()
|
||||||
|
}
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
fn absolute_position(&self) -> Rect {
|
||||||
self.xdg.absolute_desired_extents.get()
|
self.xdg.absolute_desired_extents.get()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::rect::Rect;
|
||||||
use crate::render::Renderer;
|
use crate::render::Renderer;
|
||||||
use crate::tree::toplevel::{ToplevelData, ToplevelNode};
|
use crate::tree::toplevel::{ToplevelData, ToplevelNode};
|
||||||
use crate::tree::walker::NodeVisitor;
|
use crate::tree::walker::NodeVisitor;
|
||||||
use crate::tree::FindTreeResult;
|
use crate::tree::{FindTreeResult};
|
||||||
use crate::tree::{FoundNode, Node, NodeId, ToplevelNodeId, WorkspaceNode};
|
use crate::tree::{FoundNode, Node, NodeId, ToplevelNodeId, WorkspaceNode};
|
||||||
use crate::utils::buffd::MsgParser;
|
use crate::utils::buffd::MsgParser;
|
||||||
use crate::utils::buffd::MsgParserError;
|
use crate::utils::buffd::MsgParserError;
|
||||||
|
|
@ -374,6 +374,10 @@ impl Node for XdgToplevel {
|
||||||
visitor.visit_surface(&self.xdg.surface);
|
visitor.visit_surface(&self.xdg.surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
self.xdg.workspace.get()
|
||||||
|
}
|
||||||
|
|
||||||
fn is_contained_in(&self, other: NodeId) -> bool {
|
fn is_contained_in(&self, other: NodeId) -> bool {
|
||||||
if let Some(parent) = self.parent_node.get() {
|
if let Some(parent) = self.parent_node.get() {
|
||||||
if parent.id() == other {
|
if parent.id() == other {
|
||||||
|
|
@ -443,10 +447,6 @@ impl ToplevelNode for XdgToplevel {
|
||||||
self.parent_node.get()
|
self.parent_node.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
|
||||||
self.xdg.workspace.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_node(&self) -> &dyn Node {
|
fn as_node(&self) -> &dyn Node {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::client::Client;
|
use crate::client::{Client};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal};
|
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal};
|
||||||
|
|
@ -353,6 +353,10 @@ impl Node for Xwindow {
|
||||||
visitor.visit_surface(&self.surface);
|
visitor.visit_surface(&self.surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
self.workspace.get()
|
||||||
|
}
|
||||||
|
|
||||||
fn is_contained_in(&self, other: NodeId) -> bool {
|
fn is_contained_in(&self, other: NodeId) -> bool {
|
||||||
if let Some(parent) = self.parent_node.get() {
|
if let Some(parent) = self.parent_node.get() {
|
||||||
if parent.id() == other {
|
if parent.id() == other {
|
||||||
|
|
@ -429,10 +433,6 @@ impl ToplevelNode for Xwindow {
|
||||||
self.parent_node.get()
|
self.parent_node.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
|
||||||
self.workspace.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_node(&self) -> &dyn Node {
|
fn as_node(&self) -> &dyn Node {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::client::{Client, ClientError};
|
use crate::client::{Client, ClientError};
|
||||||
use crate::ifs::wl_seat::NodeSeatState;
|
use crate::ifs::wl_seat::{NodeSeatState};
|
||||||
use crate::ifs::wl_surface::{
|
use crate::ifs::wl_surface::{
|
||||||
CommitAction, CommitContext, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError,
|
CommitAction, CommitContext, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError,
|
||||||
};
|
};
|
||||||
|
|
@ -359,10 +359,6 @@ impl Node for ZwlrLayerSurfaceV1 {
|
||||||
self.surface.clone().visit(visitor);
|
self.surface.clone().visit(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
|
||||||
renderer.render_layer_surface(self, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
fn absolute_position(&self) -> Rect {
|
||||||
self.pos.get()
|
self.pos.get()
|
||||||
}
|
}
|
||||||
|
|
@ -376,6 +372,10 @@ impl Node for ZwlrLayerSurfaceV1 {
|
||||||
self.surface.find_tree_at(x, y, tree)
|
self.surface.find_tree_at(x, y, tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||||
|
renderer.render_layer_surface(self, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
fn change_extents(self: Rc<Self>, _rect: &Rect) {
|
fn change_extents(self: Rc<Self>, _rect: &Rect) {
|
||||||
self.compute_position();
|
self.compute_position();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,10 @@ xkb_keymap {
|
||||||
<83> = 91; # KPDOT
|
<83> = 91; # KPDOT
|
||||||
<87> = 95; # F11
|
<87> = 95; # F11
|
||||||
<88> = 96; # F12
|
<88> = 96; # F12
|
||||||
|
<89> = 97; # RO
|
||||||
|
<92> = 100; # HENKAN
|
||||||
|
<93> = 101; # KATAKANAHIRAGANA
|
||||||
|
<94> = 102; # MUHENKAN
|
||||||
<96> = 104; # KPENTER
|
<96> = 104; # KPENTER
|
||||||
<97> = 105; # RIGHTCTRL
|
<97> = 105; # RIGHTCTRL
|
||||||
<98> = 106; # KPSLASH
|
<98> = 106; # KPSLASH
|
||||||
|
|
@ -103,6 +107,7 @@ xkb_keymap {
|
||||||
<111> = 119; # DELETE
|
<111> = 119; # DELETE
|
||||||
<117> = 125; # KPEQUAL
|
<117> = 125; # KPEQUAL
|
||||||
<119> = 127; # PAUSE
|
<119> = 127; # PAUSE
|
||||||
|
<124> = 132; # YEN
|
||||||
<125> = 133; # LEFTMETA
|
<125> = 133; # LEFTMETA
|
||||||
<126> = 134; # RIGHTMETA
|
<126> = 134; # RIGHTMETA
|
||||||
<139> = 147; # MENU
|
<139> = 147; # MENU
|
||||||
|
|
@ -311,6 +316,12 @@ xkb_keymap {
|
||||||
key <9> { [ 8, asterisk ] };
|
key <9> { [ 8, asterisk ] };
|
||||||
key <10> { [ 9, parenleft ] };
|
key <10> { [ 9, parenleft ] };
|
||||||
key <11> { [ 0, parenright ] };
|
key <11> { [ 0, parenright ] };
|
||||||
|
|
||||||
|
key <89> { [ dollar , asciitilde ] };
|
||||||
|
key <93> { [ ampersand , percent ] };
|
||||||
|
key <94> { [ equal , asterisk ] };
|
||||||
|
key <124> { [ at , asciicircum ] };
|
||||||
|
key <92> { [ numbersign , grave ] };
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
89
src/state.rs
89
src/state.rs
|
|
@ -136,7 +136,7 @@ impl State {
|
||||||
|
|
||||||
pub fn map_tiled(self: &Rc<Self>, node: Rc<dyn Node>) {
|
pub fn map_tiled(self: &Rc<Self>, node: Rc<dyn Node>) {
|
||||||
let seat = self.seat_queue.last();
|
let seat = self.seat_queue.last();
|
||||||
if let Some(seat) = seat {
|
if let Some(seat) = &seat {
|
||||||
if let Some(prev) = seat.last_tiled_keyboard_toplevel(&*node) {
|
if let Some(prev) = seat.last_tiled_keyboard_toplevel(&*node) {
|
||||||
if let Some(container) = prev.parent() {
|
if let Some(container) = prev.parent() {
|
||||||
if let Some(container) = container.into_container() {
|
if let Some(container) = container.into_container() {
|
||||||
|
|
@ -146,28 +146,31 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let output = {
|
let mut output = seat.map(|s| s.get_output());
|
||||||
|
if output.is_none() {
|
||||||
let outputs = self.root.outputs.lock();
|
let outputs = self.root.outputs.lock();
|
||||||
outputs.values().next().cloned()
|
output = outputs.values().next().cloned();
|
||||||
};
|
|
||||||
if let Some(output) = output {
|
|
||||||
if let Some(workspace) = output.workspace.get() {
|
|
||||||
if let Some(container) = workspace.container.get() {
|
|
||||||
container.append_child(node);
|
|
||||||
} else {
|
|
||||||
let container = ContainerNode::new(
|
|
||||||
self,
|
|
||||||
&workspace,
|
|
||||||
workspace.clone(),
|
|
||||||
node,
|
|
||||||
ContainerSplit::Horizontal,
|
|
||||||
);
|
|
||||||
workspace.set_container(&container);
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
todo!("map_tiled");
|
let output = match output {
|
||||||
|
Some(output) => output,
|
||||||
|
_ => self.dummy_output.get().unwrap(),
|
||||||
|
};
|
||||||
|
if let Some(workspace) = output.workspace.get() {
|
||||||
|
if let Some(container) = workspace.container.get() {
|
||||||
|
container.append_child(node);
|
||||||
|
} else {
|
||||||
|
let container = ContainerNode::new(
|
||||||
|
self,
|
||||||
|
&workspace,
|
||||||
|
workspace.clone(),
|
||||||
|
node,
|
||||||
|
ContainerSplit::Horizontal,
|
||||||
|
);
|
||||||
|
workspace.set_container(&container);
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log::warn!("Output has no workspace set");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_floating(
|
pub fn map_floating(
|
||||||
|
|
@ -199,4 +202,48 @@ impl State {
|
||||||
};
|
};
|
||||||
FloatNode::new(self, workspace, position, node);
|
FloatNode::new(self, workspace, position, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn show_workspace(&self, seat: &Rc<WlSeatGlobal>, name: &str) {
|
||||||
|
let output = match self.workspaces.get(name) {
|
||||||
|
Some(ws) => {
|
||||||
|
let output = ws.output.get();
|
||||||
|
if let Some(old) = output.workspace.get() {
|
||||||
|
if old.id == ws.id {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.show_workspace(&ws);
|
||||||
|
output
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let output = seat.get_output();
|
||||||
|
if output.is_dummy {
|
||||||
|
log::warn!("Not showing workspace because seat is on dummy output");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let workspace = Rc::new(WorkspaceNode {
|
||||||
|
id: self.node_ids.next(),
|
||||||
|
output: CloneCell::new(output.clone()),
|
||||||
|
position: Cell::new(Default::default()),
|
||||||
|
container: Default::default(),
|
||||||
|
stacked: Default::default(),
|
||||||
|
seat_state: Default::default(),
|
||||||
|
name: name.to_string(),
|
||||||
|
output_link: Cell::new(None),
|
||||||
|
});
|
||||||
|
workspace
|
||||||
|
.output_link
|
||||||
|
.set(Some(output.workspaces.add_last(workspace.clone())));
|
||||||
|
output.show_workspace(&workspace);
|
||||||
|
self.workspaces.set(name.to_string(), workspace);
|
||||||
|
output
|
||||||
|
}
|
||||||
|
};
|
||||||
|
output.update_render_data();
|
||||||
|
self.tree_changed();
|
||||||
|
let seats = self.globals.seats.lock();
|
||||||
|
for seat in seats.values() {
|
||||||
|
seat.workspace_changed(&output);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ impl OutputHandler {
|
||||||
let global = Rc::new(WlOutputGlobal::new(name, self.output.clone()));
|
let global = Rc::new(WlOutputGlobal::new(name, self.output.clone()));
|
||||||
let on = Rc::new(OutputNode {
|
let on = Rc::new(OutputNode {
|
||||||
id: self.state.node_ids.next(),
|
id: self.state.node_ids.next(),
|
||||||
workspaces: RefCell::new(vec![]),
|
workspaces: Default::default(),
|
||||||
position: Cell::new(Default::default()),
|
position: Cell::new(Default::default()),
|
||||||
workspace: CloneCell::new(None),
|
workspace: CloneCell::new(None),
|
||||||
seat_state: Default::default(),
|
seat_state: Default::default(),
|
||||||
|
|
@ -51,14 +51,18 @@ impl OutputHandler {
|
||||||
let workspace = Rc::new(WorkspaceNode {
|
let workspace = Rc::new(WorkspaceNode {
|
||||||
id: self.state.node_ids.next(),
|
id: self.state.node_ids.next(),
|
||||||
output: CloneCell::new(on.clone()),
|
output: CloneCell::new(on.clone()),
|
||||||
|
position: Cell::new(Default::default()),
|
||||||
container: Default::default(),
|
container: Default::default(),
|
||||||
stacked: Default::default(),
|
stacked: Default::default(),
|
||||||
seat_state: Default::default(),
|
seat_state: Default::default(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
|
output_link: Default::default(),
|
||||||
});
|
});
|
||||||
self.state.workspaces.set(name, workspace.clone());
|
self.state.workspaces.set(name, workspace.clone());
|
||||||
on.workspaces.borrow_mut().push(workspace.clone());
|
workspace
|
||||||
on.workspace.set(Some(workspace));
|
.output_link
|
||||||
|
.set(Some(on.workspaces.add_last(workspace.clone())));
|
||||||
|
on.show_workspace(&workspace);
|
||||||
on.update_render_data();
|
on.update_render_data();
|
||||||
self.state.root.outputs.set(self.output.id(), on.clone());
|
self.state.root.outputs.set(self.output.id(), on.clone());
|
||||||
self.state.add_global(&global);
|
self.state.add_global(&global);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,10 @@ pub trait Node {
|
||||||
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor);
|
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor);
|
||||||
fn visit_children(&self, visitor: &mut dyn NodeVisitor);
|
fn visit_children(&self, visitor: &mut dyn NodeVisitor);
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn is_contained_in(&self, other: NodeId) -> bool {
|
fn is_contained_in(&self, other: NodeId) -> bool {
|
||||||
let _ = other;
|
let _ = other;
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::backend::KeyState;
|
use crate::backend::{KeyState};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT};
|
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT};
|
||||||
|
|
@ -693,6 +693,10 @@ impl Node for ContainerNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
Some(self.workspace.get())
|
||||||
|
}
|
||||||
|
|
||||||
fn is_contained_in(&self, other: NodeId) -> bool {
|
fn is_contained_in(&self, other: NodeId) -> bool {
|
||||||
let parent = self.parent.get();
|
let parent = self.parent.get();
|
||||||
if parent.id() == other {
|
if parent.id() == other {
|
||||||
|
|
@ -1055,9 +1059,23 @@ impl Node for ContainerNode {
|
||||||
|
|
||||||
fn remove_child(self: Rc<Self>, child: &dyn Node) {
|
fn remove_child(self: Rc<Self>, child: &dyn Node) {
|
||||||
let node = match self.child_nodes.borrow_mut().remove(&child.id()) {
|
let node = match self.child_nodes.borrow_mut().remove(&child.id()) {
|
||||||
Some(c) => c.to_ref(),
|
Some(c) => c,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
let mut mono_child = None;
|
||||||
|
if let Some(mono) = self.mono_child.get() {
|
||||||
|
if mono.node.id() == child.id() {
|
||||||
|
self.mono_child.take();
|
||||||
|
mono_child = node.next();
|
||||||
|
if mono_child.is_none() {
|
||||||
|
mono_child = node.prev();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let node = {
|
||||||
|
let node = node;
|
||||||
|
node.to_ref()
|
||||||
|
};
|
||||||
let num_children = self.num_children.fetch_sub(1) - 1;
|
let num_children = self.num_children.fetch_sub(1) - 1;
|
||||||
if num_children == 0 {
|
if num_children == 0 {
|
||||||
self.seats.borrow_mut().clear();
|
self.seats.borrow_mut().clear();
|
||||||
|
|
@ -1080,6 +1098,9 @@ impl Node for ContainerNode {
|
||||||
sum += factor;
|
sum += factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if mono_child.is_some() {
|
||||||
|
self.mono_child.set(mono_child);
|
||||||
|
}
|
||||||
self.sum_factors.set(sum);
|
self.sum_factors.set(sum);
|
||||||
self.update_title();
|
self.update_title();
|
||||||
self.schedule_layout();
|
self.schedule_layout();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::backend::KeyState;
|
use crate::backend::{KeyState};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT};
|
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT};
|
||||||
|
|
@ -343,6 +343,10 @@ impl Node for FloatNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
Some(self.workspace.get())
|
||||||
|
}
|
||||||
|
|
||||||
fn child_title_changed(self: Rc<Self>, _child: &dyn Node, title: &str) {
|
fn child_title_changed(self: Rc<Self>, _child: &dyn Node, title: &str) {
|
||||||
let mut t = self.title.borrow_mut();
|
let mut t = self.title.borrow_mut();
|
||||||
if t.deref() != title {
|
if t.deref() != title {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_output::WlOutputGlobal;
|
use crate::ifs::wl_output::WlOutputGlobal;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||||
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||||
|
|
@ -16,14 +17,13 @@ use std::cell::{Cell, RefCell};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::ops::{Deref, Sub};
|
use std::ops::{Deref, Sub};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::fixed::Fixed;
|
|
||||||
|
|
||||||
tree_id!(OutputNodeId);
|
tree_id!(OutputNodeId);
|
||||||
pub struct OutputNode {
|
pub struct OutputNode {
|
||||||
pub id: OutputNodeId,
|
pub id: OutputNodeId,
|
||||||
pub position: Cell<Rect>,
|
pub position: Cell<Rect>,
|
||||||
pub global: Rc<WlOutputGlobal>,
|
pub global: Rc<WlOutputGlobal>,
|
||||||
pub workspaces: RefCell<Vec<Rc<WorkspaceNode>>>,
|
pub workspaces: LinkedList<Rc<WorkspaceNode>>,
|
||||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||||
pub seat_state: NodeSeatState,
|
pub seat_state: NodeSeatState,
|
||||||
pub layers: [LinkedList<Rc<ZwlrLayerSurfaceV1>>; 4],
|
pub layers: [LinkedList<Rc<ZwlrLayerSurfaceV1>>; 4],
|
||||||
|
|
@ -37,12 +37,11 @@ impl OutputNode {
|
||||||
let mut rd = self.render_data.borrow_mut();
|
let mut rd = self.render_data.borrow_mut();
|
||||||
rd.titles.clear();
|
rd.titles.clear();
|
||||||
rd.inactive_workspaces.clear();
|
rd.inactive_workspaces.clear();
|
||||||
let workspaces = self.workspaces.borrow_mut();
|
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
let font = self.state.theme.font.borrow_mut();
|
let font = self.state.theme.font.borrow_mut();
|
||||||
let th = self.state.theme.title_height.get();
|
let th = self.state.theme.title_height.get();
|
||||||
let active_id = self.workspace.get().map(|w| w.id);
|
let active_id = self.workspace.get().map(|w| w.id);
|
||||||
for ws in workspaces.deref() {
|
for ws in self.workspaces.iter() {
|
||||||
let mut title_width = th;
|
let mut title_width = th;
|
||||||
'create_texture: {
|
'create_texture: {
|
||||||
if let Some(ctx) = self.state.render_ctx.get() {
|
if let Some(ctx) = self.state.render_ctx.get() {
|
||||||
|
|
@ -78,6 +77,23 @@ impl OutputNode {
|
||||||
pos += title_width;
|
pos += title_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn show_workspace(&self, ws: &Rc<WorkspaceNode>) {
|
||||||
|
self.workspace.set(Some(ws.clone()));
|
||||||
|
ws.clone().change_extents(&self.workspace_rect());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn workspace_rect(&self) -> Rect {
|
||||||
|
let rect = self.position.get();
|
||||||
|
let th = self.state.theme.title_height.get();
|
||||||
|
Rect::new_sized(
|
||||||
|
rect.x1(),
|
||||||
|
rect.y1() + th,
|
||||||
|
rect.width(),
|
||||||
|
rect.height().sub(th).max(0),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OutputTitle {
|
pub struct OutputTitle {
|
||||||
|
|
@ -100,14 +116,6 @@ impl Debug for OutputNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node for OutputNode {
|
impl Node for OutputNode {
|
||||||
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _x: Fixed, _y: Fixed) {
|
|
||||||
seat.enter_output(&self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn leave(&self, seat: &WlSeatGlobal) {
|
|
||||||
seat.leave_output();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn id(&self) -> NodeId {
|
fn id(&self) -> NodeId {
|
||||||
self.id.into()
|
self.id.into()
|
||||||
}
|
}
|
||||||
|
|
@ -120,8 +128,9 @@ impl Node for OutputNode {
|
||||||
if detach {
|
if detach {
|
||||||
self.state.root.clone().remove_child(self);
|
self.state.root.clone().remove_child(self);
|
||||||
}
|
}
|
||||||
let mut workspaces = self.workspaces.borrow_mut();
|
self.workspace.set(None);
|
||||||
for workspace in workspaces.drain(..) {
|
let workspaces: Vec<_> = self.workspaces.iter().map(|e| e.deref().clone()).collect();
|
||||||
|
for workspace in workspaces {
|
||||||
workspace.destroy_node(false);
|
workspace.destroy_node(false);
|
||||||
}
|
}
|
||||||
self.seat_state.destroy_node(self);
|
self.seat_state.destroy_node(self);
|
||||||
|
|
@ -132,9 +141,8 @@ impl Node for OutputNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
|
fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
|
||||||
let ws = self.workspaces.borrow_mut();
|
for ws in self.workspaces.iter() {
|
||||||
for ws in ws.deref() {
|
visitor.visit_workspace(ws.deref());
|
||||||
visitor.visit_workspace(ws);
|
|
||||||
}
|
}
|
||||||
for layers in &self.layers {
|
for layers in &self.layers {
|
||||||
for surface in layers.iter() {
|
for surface in layers.iter() {
|
||||||
|
|
@ -147,20 +155,32 @@ impl Node for OutputNode {
|
||||||
self.position.get()
|
self.position.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn find_tree_at(&self, x: i32, mut y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
if let Some(ws) = self.workspace.get() {
|
let th = self.state.theme.title_height.get();
|
||||||
tree.push(FoundNode {
|
if y > th {
|
||||||
node: ws.clone(),
|
y -= th;
|
||||||
x,
|
if let Some(ws) = self.workspace.get() {
|
||||||
y,
|
tree.push(FoundNode {
|
||||||
});
|
node: ws.clone(),
|
||||||
ws.find_tree_at(x, y, tree);
|
x,
|
||||||
|
y,
|
||||||
|
});
|
||||||
|
ws.find_tree_at(x, y, tree);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FindTreeResult::AcceptsInput
|
FindTreeResult::AcceptsInput
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_child(self: Rc<Self>, _child: &dyn Node) {
|
fn remove_child(self: Rc<Self>, _child: &dyn Node) {
|
||||||
self.workspace.set(None);
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn leave(&self, seat: &WlSeatGlobal) {
|
||||||
|
seat.leave_output();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _x: Fixed, _y: Fixed) {
|
||||||
|
seat.enter_output(&self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
fn pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
@ -180,17 +200,9 @@ impl Node for OutputNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||||
let th = self.state.theme.title_height.get();
|
|
||||||
self.position.set(*rect);
|
self.position.set(*rect);
|
||||||
if let Some(c) = self.workspace.get() {
|
if let Some(c) = self.workspace.get() {
|
||||||
let wrect = Rect::new_sized(
|
c.change_extents(&self.workspace_rect());
|
||||||
rect.x1(),
|
|
||||||
rect.y1() + th,
|
|
||||||
rect.width(),
|
|
||||||
rect.height().sub(th).max(0),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
c.change_extents(&wrect);
|
|
||||||
}
|
}
|
||||||
for layer in &self.layers {
|
for layer in &self.layers {
|
||||||
for surface in layer.iter() {
|
for surface in layer.iter() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::ifs::wl_seat::SeatId;
|
use crate::ifs::wl_seat::SeatId;
|
||||||
use crate::ifs::wl_surface::WlSurface;
|
use crate::ifs::wl_surface::WlSurface;
|
||||||
use crate::tree::{Node, WorkspaceNode};
|
use crate::tree::{Node};
|
||||||
use crate::utils::linkedlist::LinkedNode;
|
use crate::utils::linkedlist::LinkedNode;
|
||||||
use crate::utils::numcell::NumCell;
|
use crate::utils::numcell::NumCell;
|
||||||
use crate::utils::smallmap::SmallMap;
|
use crate::utils::smallmap::SmallMap;
|
||||||
|
|
@ -9,7 +9,6 @@ use std::rc::Rc;
|
||||||
pub trait ToplevelNode {
|
pub trait ToplevelNode {
|
||||||
fn data(&self) -> &ToplevelData;
|
fn data(&self) -> &ToplevelData;
|
||||||
fn parent(&self) -> Option<Rc<dyn Node>>;
|
fn parent(&self) -> Option<Rc<dyn Node>>;
|
||||||
fn workspace(&self) -> Option<Rc<WorkspaceNode>>;
|
|
||||||
fn as_node(&self) -> &dyn Node;
|
fn as_node(&self) -> &dyn Node;
|
||||||
fn into_node(self: Rc<Self>) -> Rc<dyn Node>;
|
fn into_node(self: Rc<Self>) -> Rc<dyn Node>;
|
||||||
fn accepts_keyboard_focus(&self) -> bool;
|
fn accepts_keyboard_focus(&self) -> bool;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ use crate::tree::container::ContainerNode;
|
||||||
use crate::tree::walker::NodeVisitor;
|
use crate::tree::walker::NodeVisitor;
|
||||||
use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, OutputNode};
|
use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, OutputNode};
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
use crate::utils::linkedlist::LinkedList;
|
use crate::utils::linkedlist::{LinkedList, LinkedNode};
|
||||||
|
use std::cell::Cell;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
|
@ -15,16 +16,18 @@ tree_id!(WorkspaceNodeId);
|
||||||
pub struct WorkspaceNode {
|
pub struct WorkspaceNode {
|
||||||
pub id: WorkspaceNodeId,
|
pub id: WorkspaceNodeId,
|
||||||
pub output: CloneCell<Rc<OutputNode>>,
|
pub output: CloneCell<Rc<OutputNode>>,
|
||||||
|
pub position: Cell<Rect>,
|
||||||
pub container: CloneCell<Option<Rc<ContainerNode>>>,
|
pub container: CloneCell<Option<Rc<ContainerNode>>>,
|
||||||
pub stacked: LinkedList<Rc<dyn Node>>,
|
pub stacked: LinkedList<Rc<dyn Node>>,
|
||||||
pub seat_state: NodeSeatState,
|
pub seat_state: NodeSeatState,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub output_link: Cell<Option<LinkedNode<Rc<WorkspaceNode>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceNode {
|
impl WorkspaceNode {
|
||||||
pub fn set_container(self: &Rc<Self>, container: &Rc<ContainerNode>) {
|
pub fn set_container(self: &Rc<Self>, container: &Rc<ContainerNode>) {
|
||||||
let output = self.output.get().position.get();
|
let pos = self.position.get();
|
||||||
container.clone().change_extents(&output);
|
container.clone().change_extents(&pos);
|
||||||
container.clone().set_workspace(self);
|
container.clone().set_workspace(self);
|
||||||
self.container.set(Some(container.clone()));
|
self.container.set(Some(container.clone()));
|
||||||
}
|
}
|
||||||
|
|
@ -43,16 +46,13 @@ impl Node for WorkspaceNode {
|
||||||
if detach {
|
if detach {
|
||||||
self.output.get().remove_child(self);
|
self.output.get().remove_child(self);
|
||||||
}
|
}
|
||||||
|
self.output_link.set(None);
|
||||||
if let Some(container) = self.container.take() {
|
if let Some(container) = self.container.take() {
|
||||||
container.destroy_node(false);
|
container.destroy_node(false);
|
||||||
}
|
}
|
||||||
self.seat_state.destroy_node(self);
|
self.seat_state.destroy_node(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts_child(&self, node: &dyn Node) -> bool {
|
|
||||||
node.is_container()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
|
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
|
||||||
visitor.visit_workspace(&self);
|
visitor.visit_workspace(&self);
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ impl Node for WorkspaceNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
fn absolute_position(&self) -> Rect {
|
||||||
self.output.get().position.get()
|
self.position.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
|
|
@ -91,11 +91,16 @@ impl Node for WorkspaceNode {
|
||||||
renderer.render_workspace(self, x, y);
|
renderer.render_workspace(self, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn accepts_child(&self, node: &dyn Node) -> bool {
|
||||||
|
node.is_container()
|
||||||
|
}
|
||||||
|
|
||||||
fn is_workspace(&self) -> bool {
|
fn is_workspace(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||||
|
self.position.set(*rect);
|
||||||
if let Some(c) = self.container.get() {
|
if let Some(c) = self.container.get() {
|
||||||
c.change_extents(rect);
|
c.change_extents(rect);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,7 @@ msg get_log_file = 1 {
|
||||||
|
|
||||||
msg quit = 2 {
|
msg quit = 2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msg set_log_level = 3 {
|
||||||
|
level: u32,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue