autocommit 2022-04-19 13:08:10 CEST
This commit is contained in:
parent
54cf01f745
commit
c1773c0fee
12 changed files with 136 additions and 45 deletions
36
protocols.md
36
protocols.md
|
|
@ -1,6 +1,34 @@
|
|||
# implemented
|
||||
|
||||
- wayland
|
||||
- xdg-shell
|
||||
- idle-inhibit
|
||||
- linux-dma-buf
|
||||
- primary-selection
|
||||
- xdg-decoration
|
||||
- xdg-output
|
||||
- wlr-layer-shell
|
||||
- kde-server-decoration
|
||||
- mesa-drm
|
||||
|
||||
# planned
|
||||
|
||||
- presentation-time
|
||||
- viewporter
|
||||
- xdg-activation
|
||||
- drm-lease
|
||||
- session-lock
|
||||
- linux-explicit-synchronization
|
||||
- pointer-constraints
|
||||
- relative-pointer
|
||||
- tablet
|
||||
- xwayland-keyboard-grabbing
|
||||
|
||||
# todos
|
||||
|
||||
- wayland
|
||||
- wl_compositor
|
||||
- todo: version 5
|
||||
- version 5
|
||||
- wl_shm
|
||||
- support for more formats
|
||||
- wl_surface
|
||||
|
|
@ -10,7 +38,9 @@
|
|||
- scale
|
||||
- offset
|
||||
- wl_touch
|
||||
- todo
|
||||
|
||||
- xdg-shell
|
||||
- oeuo.e
|
||||
- xdg_positioner
|
||||
- set_reactive
|
||||
- xdg_toplevel
|
||||
-
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ enum MainError {
|
|||
pub const WAYLAND_DISPLAY: &str = "WAYLAND_DISPLAY";
|
||||
pub const DISPLAY: &str = "DISPLAY";
|
||||
|
||||
const STATIC_VARS: &[(&str, &str)] = &[
|
||||
("XDG_CURRENT_DESKTOP", "jay"),
|
||||
("XDG_SESSION_TYPE", "wayland"),
|
||||
("_JAVA_AWT_WM_NONREPARENTING", "1"),
|
||||
];
|
||||
|
||||
fn start_compositor2(
|
||||
forker: Rc<ForkerProxy>,
|
||||
logger: Arc<Logger>,
|
||||
|
|
@ -157,7 +163,9 @@ fn start_compositor2(
|
|||
let socket_path = Acceptor::install(&state)?;
|
||||
forker.install(&state);
|
||||
forker.setenv(WAYLAND_DISPLAY.as_bytes(), socket_path.as_bytes());
|
||||
forker.setenv(b"_JAVA_AWT_WM_NONREPARENTING", b"1");
|
||||
for (key, val) in STATIC_VARS {
|
||||
forker.setenv(key.as_bytes(), val.as_bytes());
|
||||
}
|
||||
let _compositor = engine.spawn(start_compositor3(state.clone()));
|
||||
el.run()?;
|
||||
state.xwayland.handler.borrow_mut().take();
|
||||
|
|
@ -183,6 +191,9 @@ async fn start_compositor3(state: Rc<State>) {
|
|||
|
||||
if backend.is_freestanding() {
|
||||
import_environment(&state, WAYLAND_DISPLAY, &state.socket_path.get());
|
||||
for (key, val) in STATIC_VARS {
|
||||
import_environment(&state, key, val);
|
||||
}
|
||||
}
|
||||
|
||||
let config = ConfigProxy::default(&state);
|
||||
|
|
|
|||
|
|
@ -32,16 +32,15 @@ use {
|
|||
leaks::Tracker,
|
||||
object::{Object, ObjectId},
|
||||
state::State,
|
||||
tree::{
|
||||
generic_node_visitor, ContainerSplit, FloatNode, FoundNode, Node, OutputNode,
|
||||
},
|
||||
tree::{generic_node_visitor, ContainerSplit, FloatNode, FoundNode, Node, OutputNode},
|
||||
utils::{
|
||||
asyncevent::AsyncEvent,
|
||||
buffd::{MsgParser, MsgParserError},
|
||||
clonecell::CloneCell,
|
||||
copyhashmap::CopyHashMap,
|
||||
errorfmt::ErrorFmt,
|
||||
linkedlist::{LinkedNode},
|
||||
linkedlist::LinkedNode,
|
||||
numcell::NumCell,
|
||||
rc_eq::rc_eq,
|
||||
},
|
||||
wire::{
|
||||
|
|
@ -137,8 +136,12 @@ pub struct WlSeatGlobal {
|
|||
tree_changed_handler: Cell<Option<SpawnedFuture<()>>>,
|
||||
output: CloneCell<Rc<OutputNode>>,
|
||||
desired_known_cursor: Cell<Option<KnownCursor>>,
|
||||
changes: NumCell<u32>,
|
||||
}
|
||||
|
||||
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
||||
const CHANGE_TREE: u32 = 1 << 1;
|
||||
|
||||
impl WlSeatGlobal {
|
||||
pub fn new(name: GlobalName, seat_name: &str, state: &Rc<State>) -> Rc<Self> {
|
||||
let slf = Rc::new(Self {
|
||||
|
|
@ -174,13 +177,15 @@ impl WlSeatGlobal {
|
|||
tree_changed_handler: Cell::new(None),
|
||||
output: CloneCell::new(state.dummy_output.get().unwrap()),
|
||||
desired_known_cursor: Cell::new(None),
|
||||
changes: NumCell::new(CHANGE_CURSOR_MOVED | CHANGE_TREE),
|
||||
});
|
||||
let seat = slf.clone();
|
||||
let future = state.eng.spawn(async move {
|
||||
loop {
|
||||
seat.tree_changed.triggered().await;
|
||||
seat.state.tree_changed_sent.set(false);
|
||||
seat.tree_changed();
|
||||
seat.changes.or_assign(CHANGE_TREE);
|
||||
seat.apply_changes();
|
||||
}
|
||||
});
|
||||
slf.tree_changed_handler.set(Some(future));
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ use {
|
|||
AXIS_SOURCE_SINCE_VERSION, AXIS_STOP_SINCE_VERSION,
|
||||
POINTER_FRAME_SINCE_VERSION, WHEEL_TILT, WHEEL_TILT_SINCE_VERSION,
|
||||
},
|
||||
Dnd, SeatId, WlSeat, WlSeatGlobal,
|
||||
Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED,
|
||||
},
|
||||
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
|
||||
},
|
||||
object::ObjectId,
|
||||
tree::{FloatNode, Node, SizedNode, ToplevelNode},
|
||||
utils::{clonecell::CloneCell, smallmap::SmallMap},
|
||||
utils::{bitflags::BitflagsExt, clonecell::CloneCell, smallmap::SmallMap},
|
||||
wire::WlDataOfferId,
|
||||
xkbcommon::{ModifierState, XKB_KEY_DOWN, XKB_KEY_UP},
|
||||
},
|
||||
|
|
@ -400,7 +400,11 @@ impl WlSeatGlobal {
|
|||
|
||||
fn set_new_position(self: &Rc<Self>, x: Fixed, y: Fixed) {
|
||||
self.pos.set((x, y));
|
||||
self.handle_new_position(true);
|
||||
if let Some(cursor) = self.cursor.get() {
|
||||
cursor.set_position(x.round_down(), y.round_down());
|
||||
}
|
||||
self.changes.or_assign(CHANGE_CURSOR_MOVED);
|
||||
self.apply_changes();
|
||||
}
|
||||
|
||||
pub fn add_shortcut(&self, mods: Modifiers, keysym: KeySym) {
|
||||
|
|
@ -415,18 +419,9 @@ impl WlSeatGlobal {
|
|||
self.tree_changed.trigger();
|
||||
}
|
||||
|
||||
pub(super) fn tree_changed(self: &Rc<Self>) {
|
||||
self.handle_new_position(false);
|
||||
}
|
||||
|
||||
fn handle_new_position(self: &Rc<Self>, pos_changed: bool) {
|
||||
let (x, y) = self.pos.get();
|
||||
if pos_changed {
|
||||
if let Some(cursor) = self.cursor.get() {
|
||||
cursor.set_position(x.round_down(), y.round_down());
|
||||
}
|
||||
}
|
||||
self.pointer_owner.handle_pointer_position(self);
|
||||
pub(super) fn apply_changes(self: &Rc<Self>) {
|
||||
self.pointer_owner.apply_changes(self);
|
||||
self.changes.set(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +487,7 @@ impl WlSeatGlobal {
|
|||
// Enter callbacks
|
||||
impl WlSeatGlobal {
|
||||
pub fn enter_toplevel(self: &Rc<Self>, n: Rc<dyn ToplevelNode>) {
|
||||
if n.accepts_keyboard_focus() {
|
||||
if n.accepts_keyboard_focus() && self.changes.get().contains(CHANGE_CURSOR_MOVED) {
|
||||
self.focus_toplevel(n);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ impl PointerOwnerHolder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
self.owner.get().handle_pointer_position(seat)
|
||||
pub fn apply_changes(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
self.owner.get().apply_changes(seat)
|
||||
}
|
||||
|
||||
pub fn start_drag(
|
||||
|
|
@ -99,7 +99,7 @@ impl PointerOwnerHolder {
|
|||
trait PointerOwner {
|
||||
fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState);
|
||||
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>>;
|
||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>);
|
||||
fn apply_changes(&self, seat: &Rc<WlSeatGlobal>);
|
||||
fn start_drag(
|
||||
&self,
|
||||
seat: &Rc<WlSeatGlobal>,
|
||||
|
|
@ -155,7 +155,7 @@ impl PointerOwner for DefaultPointerOwner {
|
|||
seat.pointer_node()
|
||||
}
|
||||
|
||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
fn apply_changes(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
let (x, y) = seat.pos.get();
|
||||
let mut found_tree = seat.found_tree.borrow_mut();
|
||||
let mut stack = seat.pointer_stack.borrow_mut();
|
||||
|
|
@ -278,7 +278,7 @@ impl PointerOwner for GrabPointerOwner {
|
|||
Some(self.node.clone())
|
||||
}
|
||||
|
||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
fn apply_changes(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
let (x, y) = seat.pos.get();
|
||||
let pos = self.node.node_absolute_position();
|
||||
let (x_int, y_int) = pos.translate(x.round_down(), y.round_down());
|
||||
|
|
@ -341,7 +341,7 @@ impl PointerOwner for GrabPointerOwner {
|
|||
// old.unfocus(seat);
|
||||
// }
|
||||
seat.pointer_owner.owner.set(pointer_owner.clone());
|
||||
pointer_owner.handle_pointer_position(seat);
|
||||
pointer_owner.apply_changes(seat);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +405,7 @@ impl PointerOwner for DndPointerOwner {
|
|||
None
|
||||
}
|
||||
|
||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
fn apply_changes(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
let (x, y) = seat.pos.get();
|
||||
let (x_int, y_int) = (x.round_down(), y.round_down());
|
||||
let (node, x_int, y_int) = {
|
||||
|
|
|
|||
|
|
@ -293,7 +293,9 @@ impl SizedNode for XdgPopup {
|
|||
}
|
||||
|
||||
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||
self.parent.get().and_then(|x| x.workspace.get().map(|w| w as Rc<dyn Node>))
|
||||
self.parent
|
||||
.get()
|
||||
.and_then(|x| x.workspace.get().map(|w| w as Rc<dyn Node>))
|
||||
}
|
||||
|
||||
fn set_visible(&self, visible: bool) {
|
||||
|
|
|
|||
|
|
@ -319,9 +319,9 @@ impl XdgToplevel {
|
|||
}
|
||||
|
||||
fn map_floating(self: &Rc<Self>, workspace: &Rc<WorkspaceNode>) {
|
||||
let extents = self.xdg.extents.get();
|
||||
let (width, height) = self.toplevel_data.float_size(workspace);
|
||||
let state = &self.xdg.surface.client.state;
|
||||
state.map_floating(self.clone(), extents.width(), extents.height(), workspace);
|
||||
state.map_floating(self.clone(), width, height, workspace);
|
||||
}
|
||||
|
||||
fn map_child(self: &Rc<Self>, parent: &XdgToplevel) {
|
||||
|
|
@ -459,6 +459,10 @@ impl SizedNode for XdgToplevel {
|
|||
let nh = rect.height();
|
||||
let de = self.xdg.absolute_desired_extents.get();
|
||||
if de.width() != nw || de.height() != nh {
|
||||
if self.toplevel_data.is_floating.get() {
|
||||
self.toplevel_data.float_width.set(rect.width());
|
||||
self.toplevel_data.float_height.set(rect.height());
|
||||
}
|
||||
self.send_configure_checked(nw, nh);
|
||||
self.xdg.do_send_configure();
|
||||
self.xdg.surface.client.flush();
|
||||
|
|
@ -471,6 +475,7 @@ impl SizedNode for XdgToplevel {
|
|||
}
|
||||
|
||||
fn set_parent(self: &Rc<Self>, parent: Rc<dyn Node>) {
|
||||
self.toplevel_data.is_floating.set(parent.node_is_float());
|
||||
self.parent_node.set(Some(parent));
|
||||
self.notify_parent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,6 +435,10 @@ impl SizedNode for Xwindow {
|
|||
// log::info!("xwin {} change_extents {:?}", self.data.window_id, rect);
|
||||
let old = self.data.info.extents.replace(*rect);
|
||||
if old != *rect {
|
||||
if self.toplevel_data.is_floating.get() {
|
||||
self.toplevel_data.float_width.set(rect.width());
|
||||
self.toplevel_data.float_height.set(rect.height());
|
||||
}
|
||||
if !self.data.info.override_redirect.get() {
|
||||
self.data
|
||||
.state
|
||||
|
|
@ -453,6 +457,7 @@ impl SizedNode for Xwindow {
|
|||
}
|
||||
|
||||
fn set_parent(self: &Rc<Self>, parent: Rc<dyn Node>) {
|
||||
self.toplevel_data.is_floating.set(parent.node_is_float());
|
||||
self.parent_node.set(Some(parent));
|
||||
self.notify_parent();
|
||||
}
|
||||
|
|
@ -508,10 +513,10 @@ impl ToplevelNode for Xwindow {
|
|||
self.data.state.map_tiled(self.clone());
|
||||
} else if let Some(ws) = self.workspace.get() {
|
||||
parent.node_remove_child(&*self);
|
||||
let extents = self.data.info.extents.get();
|
||||
let (width, height) = self.toplevel_data.float_size(&ws);
|
||||
self.data
|
||||
.state
|
||||
.map_floating(self.clone(), extents.width(), extents.height(), &ws);
|
||||
.map_floating(self.clone(), width, height, &ws);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
dbus::{DbusError, DbusSocket, SignalHandler, FALSE},
|
||||
utils::errorfmt::ErrorFmt,
|
||||
wire_dbus::{
|
||||
org,
|
||||
org::freedesktop::login1::{
|
||||
|
|
@ -81,10 +82,22 @@ impl Session {
|
|||
org::freedesktop::login1::session::TakeControl { force: FALSE },
|
||||
)
|
||||
.await;
|
||||
match res {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(LogindError::TakeControl(e)),
|
||||
if let Err(e) = res {
|
||||
return Err(LogindError::TakeControl(e));
|
||||
}
|
||||
self.socket.call(
|
||||
LOGIND_NAME,
|
||||
&self.session_path,
|
||||
org::freedesktop::login1::session::SetType {
|
||||
ty: "wayland".into(),
|
||||
},
|
||||
|res| {
|
||||
if let Err(e) = res {
|
||||
log::warn!("Could not change session type to wayland: {}", ErrorFmt(e));
|
||||
}
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_device<F>(&self, dev: c::dev_t, f: F)
|
||||
|
|
|
|||
12
src/state.rs
12
src/state.rs
|
|
@ -209,9 +209,15 @@ impl State {
|
|||
}
|
||||
|
||||
pub fn map_tiled(self: &Rc<Self>, node: Rc<dyn Node>) {
|
||||
let output = self
|
||||
.seat_queue
|
||||
.last()
|
||||
let seat = self.seat_queue.last();
|
||||
self.do_map_tiled(seat.as_deref(), node.clone());
|
||||
if let Some(seat) = seat {
|
||||
node.node_do_focus(&seat, Direction::Unspecified);
|
||||
}
|
||||
}
|
||||
|
||||
fn do_map_tiled(self: &Rc<Self>, seat: Option<&Rc<WlSeatGlobal>>, node: Rc<dyn Node>) {
|
||||
let output = seat
|
||||
.map(|s| s.get_output())
|
||||
.or_else(|| self.root.outputs.lock().values().next().cloned())
|
||||
.or_else(|| self.dummy_output.get())
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use {
|
||||
crate::{
|
||||
ifs::{wl_seat::SeatId, wl_surface::WlSurface},
|
||||
tree::Node,
|
||||
tree::{Node, WorkspaceNode},
|
||||
utils::{numcell::NumCell, smallmap::SmallMap},
|
||||
},
|
||||
std::rc::Rc,
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
tree_id!(ToplevelNodeId);
|
||||
|
|
@ -24,12 +24,28 @@ pub trait ToplevelNode {
|
|||
pub struct ToplevelData {
|
||||
pub active_surfaces: NumCell<u32>,
|
||||
pub focus_surface: SmallMap<SeatId, Rc<WlSurface>, 1>,
|
||||
pub is_floating: Cell<bool>,
|
||||
pub float_width: Cell<i32>,
|
||||
pub float_height: Cell<i32>,
|
||||
}
|
||||
|
||||
impl ToplevelData {
|
||||
pub fn clear(&self) {
|
||||
self.focus_surface.clear();
|
||||
}
|
||||
|
||||
pub fn float_size(&self, ws: &WorkspaceNode) -> (i32, i32) {
|
||||
let output = ws.output.get().global.pos.get();
|
||||
let mut width = self.float_width.get();
|
||||
let mut height = self.float_height.get();
|
||||
if width == 0 {
|
||||
width = output.width() / 2;
|
||||
}
|
||||
if height == 0 {
|
||||
height = output.height() / 2;
|
||||
}
|
||||
(width, height)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dyn ToplevelNode + 'a {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ fn TakeDevice(major: u32, minor: u32) {
|
|||
|
||||
fn PauseDeviceComplete(major: u32, minor: u32) { }
|
||||
|
||||
fn SetType(ty: string) {
|
||||
}
|
||||
|
||||
prop Seat = struct(string, object_path)
|
||||
|
||||
sig PauseDevice {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue