mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Fix xwayland and cleanup
This commit is contained in:
parent
abb21d9924
commit
c0fe55003b
7 changed files with 116 additions and 98 deletions
|
@ -31,15 +31,10 @@ pub struct Dummy {
|
|||
}
|
||||
|
||||
impl Backend {
|
||||
fn dummy_mut(&mut self) -> &mut Dummy {
|
||||
fn dummy_mut(&mut self) -> &Dummy {
|
||||
let Backend::Dummy(dummy) = self else { unreachable!() };
|
||||
dummy
|
||||
}
|
||||
|
||||
#[cfg(feature = "wlcs")]
|
||||
pub fn wlcs_mut(&mut self) -> &mut Wlcs {
|
||||
&mut self.dummy_mut().wlcs_state
|
||||
}
|
||||
}
|
||||
|
||||
impl BackendData for Dummy {
|
||||
|
@ -121,7 +116,7 @@ pub fn setup_dummy(
|
|||
|
||||
state.space.map_output(&output, (0, 0));
|
||||
|
||||
/* if let Err(err) = state.xwayland.start(
|
||||
if let Err(err) = state.xwayland.start(
|
||||
state.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
|
@ -129,7 +124,7 @@ pub fn setup_dummy(
|
|||
|_| {},
|
||||
) {
|
||||
tracing::error!("Failed to start XWayland: {err}");
|
||||
} */
|
||||
}
|
||||
|
||||
Ok((state, event_loop))
|
||||
}
|
||||
|
|
|
@ -1,9 +1,89 @@
|
|||
use std::{collections::HashMap, sync::{atomic::AtomicBool, Arc}};
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use smithay::reexports::wayland_server::Client;
|
||||
use smithay::{
|
||||
backend::renderer::{test::DummyRenderer, ImportMemWl},
|
||||
output::{Output, Subpixel},
|
||||
reexports::{
|
||||
calloop::EventLoop,
|
||||
wayland_server::{Client, Display},
|
||||
},
|
||||
utils::Transform,
|
||||
};
|
||||
|
||||
use crate::state::State;
|
||||
|
||||
use super::{dummy::Dummy, Backend};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Wlcs {
|
||||
pub clients: HashMap<i32, Client>,
|
||||
pub running: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl Backend {
|
||||
pub fn wlcs_mut(&mut self) -> &mut Wlcs {
|
||||
let Backend::Dummy(dummy) = self else { unreachable!() };
|
||||
&mut dummy.wlcs_state
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_wlcs_dummy(
|
||||
no_config: bool,
|
||||
config_dir: Option<PathBuf>,
|
||||
) -> anyhow::Result<(State, EventLoop<'static, State>)> {
|
||||
let event_loop: EventLoop<State> = EventLoop::try_new()?;
|
||||
|
||||
let display: Display<State> = Display::new()?;
|
||||
let display_handle = display.handle();
|
||||
|
||||
let loop_handle = event_loop.handle();
|
||||
|
||||
let mode = smithay::output::Mode {
|
||||
size: (1920, 1080).into(),
|
||||
refresh: 60_000,
|
||||
};
|
||||
|
||||
let physical_properties = smithay::output::PhysicalProperties {
|
||||
size: (0, 0).into(),
|
||||
subpixel: Subpixel::Unknown,
|
||||
make: "Pinnacle".to_string(),
|
||||
model: "Dummy Window".to_string(),
|
||||
};
|
||||
|
||||
let output = Output::new("Pinnacle Window".to_string(), physical_properties);
|
||||
|
||||
output.create_global::<State>(&display_handle);
|
||||
|
||||
output.change_current_state(
|
||||
Some(mode),
|
||||
Some(Transform::Flipped180),
|
||||
None,
|
||||
Some((0, 0).into()),
|
||||
);
|
||||
|
||||
output.set_preferred(mode);
|
||||
|
||||
let renderer = DummyRenderer::new();
|
||||
let shm_formats = renderer.shm_formats();
|
||||
|
||||
let backend = Dummy {
|
||||
renderer,
|
||||
wlcs_state: Wlcs::default(),
|
||||
};
|
||||
|
||||
let mut state = State::init(
|
||||
super::Backend::Dummy(backend),
|
||||
display,
|
||||
event_loop.get_signal(),
|
||||
loop_handle,
|
||||
no_config,
|
||||
config_dir,
|
||||
)?;
|
||||
|
||||
state.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
state.shm_state.update_formats(shm_formats);
|
||||
|
||||
state.space.map_output(&output, (0, 0));
|
||||
|
||||
Ok((state, event_loop))
|
||||
}
|
||||
|
|
|
@ -564,17 +564,10 @@ impl State {
|
|||
}
|
||||
}));
|
||||
}
|
||||
None => {
|
||||
self.grpc_server_join_handle = Some(tokio::spawn(async move {
|
||||
if let Err(err) = grpc_server.serve_with_incoming(uds_stream).await {
|
||||
error!("gRPC server error: {err}");
|
||||
}
|
||||
}));
|
||||
}
|
||||
// FIXME: Not really high priority but if you somehow reload the config really, REALLY
|
||||
// | fast at startup then I think there's a chance that the gRPC server
|
||||
// | could get started twice.
|
||||
/* None => self.schedule(
|
||||
None => self.schedule(
|
||||
|state| state.xdisplay.is_some(),
|
||||
move |state| {
|
||||
state.grpc_server_join_handle = Some(tokio::spawn(async move {
|
||||
|
@ -583,7 +576,7 @@ impl State {
|
|||
}
|
||||
}));
|
||||
},
|
||||
), */
|
||||
),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1,46 +1,6 @@
|
|||
# This metaconfig.toml file dictates what config Pinnacle will run.
|
||||
#
|
||||
# When running Pinnacle, the compositor will look in the following directories for a metaconfig.toml file,
|
||||
# in order from top to bottom:
|
||||
# $PINNACLE_CONFIG_DIR
|
||||
# $XDG_CONFIG_HOME/pinnacle/
|
||||
# ~/.config/pinnacle/
|
||||
#
|
||||
# When Pinnacle finds a metaconfig.toml file, it will execute the command provided to `command`.
|
||||
# To use a Rust config, this should be changed to something like ["cargo", "run"].
|
||||
#
|
||||
# Because configuration is done using an external process, if it ever crashes, you lose all of your keybinds.
|
||||
# The compositor will load the default config if that happens, but in the event that you don't have
|
||||
# the necessary dependencies for it to run, you may get softlocked.
|
||||
# In order prevent you from getting stuck in the compositor, you must define keybinds to reload your config
|
||||
# and kill Pinnacle.
|
||||
#
|
||||
# More details on each setting can be found below.
|
||||
|
||||
# The command Pinnacle will run on startup and when you reload your config.
|
||||
# Paths are relative to the directory the metaconfig.toml file is in.
|
||||
# This must be an array.
|
||||
command = ["./pinnacle-config"]
|
||||
|
||||
### Keybinds ###
|
||||
# Each keybind takes in a table with two fields: `modifiers` and `key`.
|
||||
# - `modifiers` can be one of "Ctrl", "Alt", "Shift", or "Super".
|
||||
# - `key` can be a string of any lowercase letter, number,
|
||||
# "numN" where N is a number for numpad keys, or "esc"/"escape".
|
||||
# Support for any xkbcommon key is planned for a future update.
|
||||
|
||||
# The keybind that will reload your config.
|
||||
reload_keybind = { modifiers = ["Ctrl", "Alt"], key = "r" }
|
||||
# The keybind that will kill Pinnacle.
|
||||
kill_keybind = { modifiers = ["Ctrl", "Alt", "Shift"], key = "escape" }
|
||||
|
||||
### Socket directory ###
|
||||
# Pinnacle will open a Unix socket at `$XDG_RUNTIME_DIR` by default, falling back to `/tmp` if it doesn't exist.
|
||||
# If you want/need to change this, use the `socket_dir` setting set to the directory of your choosing.
|
||||
#
|
||||
# socket_dir = "/your/dir/here/"
|
||||
|
||||
### Environment Variables ###
|
||||
# If you need to spawn your config with any environment variables, list them here.
|
||||
[envs]
|
||||
# key = "value"
|
||||
|
|
|
@ -1,36 +1,12 @@
|
|||
use pinnacle_api::layout::{CyclingLayoutManager, MasterStackLayout};
|
||||
use pinnacle_api::ApiModules;
|
||||
|
||||
// Pinnacle needs to perform some setup before and after your config.
|
||||
// The `#[pinnacle_api::config(modules)]` attribute does so and
|
||||
// will bind all the config structs to the provided identifier.
|
||||
#[pinnacle_api::config(modules)]
|
||||
async fn main() {
|
||||
// Deconstruct to get all the APIs.
|
||||
#[allow(unused_variables)]
|
||||
let ApiModules {
|
||||
pinnacle,
|
||||
process,
|
||||
window,
|
||||
input,
|
||||
output,
|
||||
tag,
|
||||
layout,
|
||||
render,
|
||||
} = modules;
|
||||
let ApiModules { layout, .. } = modules;
|
||||
|
||||
let _layout_requester = layout.set_manager(CyclingLayoutManager::new([
|
||||
Box::<MasterStackLayout>::default() as _,
|
||||
]));
|
||||
|
||||
// Setup all monitors with tags "1" through "5"
|
||||
output.connect_for_all(move |op| {
|
||||
let tags = tag.add(op, ["tag"]);
|
||||
tags.first().unwrap().set_active(true);
|
||||
});
|
||||
|
||||
// Enable sloppy focus
|
||||
/* window.connect_signal(WindowSignal::PointerEnter(Box::new(|win| {
|
||||
win.set_focused(true);
|
||||
}))); */
|
||||
}
|
||||
|
|
|
@ -202,22 +202,28 @@ impl Wlcs for PinnacleHandle {
|
|||
}
|
||||
|
||||
fn create_pointer(&mut self) -> Option<Self::Pointer> {
|
||||
let device_id = new_device_id();
|
||||
self.server_conn
|
||||
.as_ref()
|
||||
.map(|conn| conn.sender.clone())
|
||||
.map(|sender| PointerHandle {
|
||||
device_id: new_device_id(),
|
||||
sender,
|
||||
.map(|sender| {
|
||||
sender
|
||||
.send(WlcsEvent::NewPointer { device_id })
|
||||
.expect("failed to send new_pointer");
|
||||
PointerHandle { device_id, sender }
|
||||
})
|
||||
}
|
||||
|
||||
fn create_touch(&mut self) -> Option<Self::Touch> {
|
||||
let device_id = new_device_id();
|
||||
self.server_conn
|
||||
.as_ref()
|
||||
.map(|conn| conn.sender.clone())
|
||||
.map(|sender| TouchHandle {
|
||||
device_id: new_device_id(),
|
||||
sender,
|
||||
.map(|sender| {
|
||||
sender
|
||||
.send(WlcsEvent::NewTouch { device_id })
|
||||
.expect("failed to send new_touch");
|
||||
TouchHandle { device_id, sender }
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use pinnacle::{
|
||||
backend::dummy::setup_dummy,
|
||||
backend::wlcs::setup_wlcs_dummy,
|
||||
state::{ClientState, State},
|
||||
};
|
||||
use smithay::{
|
||||
backend::input::{ButtonState, DeviceCapability, InputEvent},
|
||||
reexports::{
|
||||
calloop::channel::{Channel, Event},
|
||||
wayland_server::Resource,
|
||||
wayland_server::{Client, Resource},
|
||||
},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ pub(crate) fn run(channel: Channel<WlcsEvent>) {
|
|||
&std::env::var("PINNACLE_WLCS_CONFIG_PATH").expect("PINNACLE_WLCS_CONFIG_PATH not set");
|
||||
|
||||
let (mut state, mut event_loop) =
|
||||
setup_dummy(false, Some(config_path.into())).expect("failed to setup dummy backend");
|
||||
setup_wlcs_dummy(false, Some(config_path.into())).expect("failed to setup dummy backend");
|
||||
|
||||
event_loop
|
||||
.handle()
|
||||
|
@ -40,19 +40,27 @@ pub(crate) fn run(channel: Channel<WlcsEvent>) {
|
|||
let rt = tokio::runtime::Runtime::new().expect("failed to create tokio runtime");
|
||||
let _handle = rt.enter();
|
||||
|
||||
// FIXME: once starting pinnacle without xwayland is a thing, handle this
|
||||
// | properly; in this case, we probably no longer need to start the
|
||||
// | config manually anymore either, as this is only needed now,
|
||||
// | because the config is started after xwayland reports its ready
|
||||
|
||||
// when xdiplay is None when starting the config, the grpc server is not
|
||||
// started, until it is set; this bypasses this for now
|
||||
state.xdisplay = Some(u32::MAX);
|
||||
if let Err(err) = state.start_config(config_path) {
|
||||
panic!("failed to start config: {err}");
|
||||
}
|
||||
|
||||
// FIXME: different sock_dir per instance?
|
||||
// FIXME: use a custom socker_dir to avoid having to number sockets
|
||||
|
||||
// wait for the config to connect to the layout service
|
||||
while state.layout_state.layout_request_sender.is_none() {
|
||||
event_loop
|
||||
.dispatch(Some(Duration::from_millis(10)), &mut state)
|
||||
.expect("event_loop error while waiting for config");
|
||||
}
|
||||
|
||||
// TODO: handle no-xwayland properly
|
||||
|
||||
event_loop
|
||||
.run(None, &mut state, |state| {
|
||||
state.update_pointer_focus();
|
||||
|
@ -72,7 +80,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
match event {
|
||||
WlcsEvent::Stop => state.shutdown(),
|
||||
WlcsEvent::NewClient { stream, client_id } => {
|
||||
let client: smithay::reexports::wayland_server::Client = state
|
||||
let client: Client = state
|
||||
.display_handle
|
||||
.insert_client(stream, Arc::new(ClientState::default()))
|
||||
.expect("failed to insert new client");
|
||||
|
|
Loading…
Reference in a new issue