diff --git a/Cargo.lock b/Cargo.lock
index 44b0a032..8ff3ab2f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -368,11 +368,11 @@ dependencies = [
"once_cell",
"pretty_env_logger",
"rust-embed",
- "smithay-client-toolkit",
"tokio",
- "wayland-client",
+ "wayland-backend",
+ "wayland-client 0.30.0-beta.4",
"wayland-commons",
- "wayland-scanner",
+ "wayland-scanner 0.30.0-beta.4",
]
[[package]]
@@ -1829,6 +1829,12 @@ dependencies = [
"winapi-util",
]
+[[package]]
+name = "scoped-tls"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
+
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -1978,7 +1984,7 @@ dependencies = [
"memmap2",
"nix 0.22.3",
"pkg-config",
- "wayland-client",
+ "wayland-client 0.29.4",
"wayland-cursor",
"wayland-protocols",
]
@@ -2231,6 +2237,20 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+[[package]]
+name = "wayland-backend"
+version = "0.1.0-beta.4"
+source = "git+https://github.com/smithay/wayland-rs.git#797f697a66f8541327cbaac319692ec8d2395a38"
+dependencies = [
+ "cc",
+ "downcast-rs",
+ "log",
+ "nix 0.24.1",
+ "scoped-tls",
+ "smallvec",
+ "wayland-sys 0.30.0-beta.4",
+]
+
[[package]]
name = "wayland-client"
version = "0.29.4"
@@ -2242,8 +2262,23 @@ dependencies = [
"libc",
"nix 0.22.3",
"wayland-commons",
- "wayland-scanner",
- "wayland-sys",
+ "wayland-scanner 0.29.4",
+ "wayland-sys 0.29.4",
+]
+
+[[package]]
+name = "wayland-client"
+version = "0.30.0-beta.4"
+source = "git+https://github.com/smithay/wayland-rs.git#797f697a66f8541327cbaac319692ec8d2395a38"
+dependencies = [
+ "bitflags",
+ "futures-channel",
+ "futures-core",
+ "log",
+ "nix 0.24.1",
+ "thiserror",
+ "wayland-backend",
+ "wayland-scanner 0.30.0-beta.4",
]
[[package]]
@@ -2255,7 +2290,7 @@ dependencies = [
"nix 0.22.3",
"once_cell",
"smallvec",
- "wayland-sys",
+ "wayland-sys 0.29.4",
]
[[package]]
@@ -2265,7 +2300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd"
dependencies = [
"nix 0.22.3",
- "wayland-client",
+ "wayland-client 0.29.4",
"xcursor",
]
@@ -2276,9 +2311,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741"
dependencies = [
"bitflags",
- "wayland-client",
+ "wayland-client 0.29.4",
"wayland-commons",
- "wayland-scanner",
+ "wayland-scanner 0.29.4",
]
[[package]]
@@ -2292,6 +2327,17 @@ dependencies = [
"xml-rs",
]
+[[package]]
+name = "wayland-scanner"
+version = "0.30.0-beta.4"
+source = "git+https://github.com/smithay/wayland-rs.git#797f697a66f8541327cbaac319692ec8d2395a38"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "xml-rs",
+]
+
[[package]]
name = "wayland-sys"
version = "0.29.4"
@@ -2301,6 +2347,16 @@ dependencies = [
"pkg-config",
]
+[[package]]
+name = "wayland-sys"
+version = "0.30.0-beta.4"
+source = "git+https://github.com/smithay/wayland-rs.git#797f697a66f8541327cbaac319692ec8d2395a38"
+dependencies = [
+ "dlib",
+ "log",
+ "pkg-config",
+]
+
[[package]]
name = "wepoll-ffi"
version = "0.1.2"
diff --git a/applets/cosmic-applet-workspaces/Cargo.toml b/applets/cosmic-applet-workspaces/Cargo.toml
index acbaf4bd..9a22dbcb 100644
--- a/applets/cosmic-applet-workspaces/Cargo.toml
+++ b/applets/cosmic-applet-workspaces/Cargo.toml
@@ -17,10 +17,10 @@ i18n-embed = { version = "0.13.4", features = ["fluent-system", "desktop-request
i18n-embed-fl = "0.6.4"
rust-embed = "6.3.0"
tokio = { version = "1.16.1", features = ["sync"] }
-wayland-client = "0.29.4"
wayland-commons = "0.29.4"
-sctk = { package = "smithay-client-toolkit", git = "https://github.com/wash2/client-toolkit.git", default-features = false, features = ["calloop"] }
+wayland-scanner = { git = "https://github.com/smithay/wayland-rs.git", version = "0.30.0-beta.4"}
+wayland-backend = { version = "0.1.0-beta.4", git = "https://github.com/smithay/wayland-rs.git" }
+wayland-client = { version = "0.30.0-beta.4", git = "https://github.com/smithay/wayland-rs.git" }
[build-dependencies]
gio = "0.15.10"
-wayland-scanner = "0.29"
diff --git a/applets/cosmic-applet-workspaces/build.rs b/applets/cosmic-applet-workspaces/build.rs
index d99ec86a..49c3dbed 100644
--- a/applets/cosmic-applet-workspaces/build.rs
+++ b/applets/cosmic-applet-workspaces/build.rs
@@ -1,7 +1,5 @@
-extern crate wayland_scanner;
-
use std::{env, path::PathBuf, process::Command};
-use wayland_scanner::{generate_code, Side};
+// use wayland_scanner::{generate_client_code};
fn main() {
if let Some(output) = Command::new("git")
@@ -17,13 +15,12 @@ fn main() {
"data/resources/resources.gresource.xml",
"compiled.gresource",
);
- let dest = PathBuf::from(&env::var("OUT_DIR").unwrap());
- // Location of the xml file, relative to the `Cargo.toml`
- let ext_workspace_protocol_file = "data/resources/ext-workspace-unstable-v1.xml";
- // Target directory for the generate files
- generate_code(
- ext_workspace_protocol_file,
- &dest.join("ext_workspace.rs"),
- Side::Client,
- );
+ // let dest = PathBuf::from(&env::var("OUT_DIR").unwrap());
+ // // Location of the xml file, relative to the `Cargo.toml`
+ // let ext_workspace_protocol_file = "data/resources/ext-workspace-unstable-v1.xml";
+ // // Target directory for the generate files
+ // generate_client_code!(
+ // ext_workspace_protocol_file,
+ // &dest.join("ext_workspace.rs"),
+ // );
}
diff --git a/applets/cosmic-applet-workspaces/src/ext-workspace-unstable-v1.xml b/applets/cosmic-applet-workspaces/src/ext-workspace-unstable-v1.xml
new file mode 100644
index 00000000..24410b62
--- /dev/null
+++ b/applets/cosmic-applet-workspaces/src/ext-workspace-unstable-v1.xml
@@ -0,0 +1,306 @@
+
+
+
+ Copyright © 2019 Christopher Billington
+ Copyright © 2020 Ilia Bozhinov
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+
+
+
+
+ Workspaces, also called virtual desktops, are groups of surfaces. A
+ compositor with a concept of workspaces may only show some such groups of
+ surfaces (those of 'active' workspaces) at a time. 'Activating' a
+ workspace is a request for the compositor to display that workspace's
+ surfaces as normal, whereas the compositor may hide or otherwise
+ de-emphasise surfaces that are associated only with 'inactive' workspaces.
+ Workspaces are grouped by which sets of outputs they correspond to, and
+ may contain surfaces only from those outputs. In this way, it is possible
+ for each output to have its own set of workspaces, or for all outputs (or
+ any other arbitrary grouping) to share workspaces. Compositors may
+ optionally conceptually arrange each group of workspaces in an
+ N-dimensional grid.
+
+ The purpose of this protocol is to enable the creation of taskbars and
+ docks by providing them with a list of workspaces and their properties,
+ and allowing them to activate and deactivate workspaces.
+
+ After a client binds the zext_workspace_manager_v1, each workspace will be
+ sent via the workspace event.
+
+
+
+
+ This event is emitted whenever a new workspace group has been created.
+
+ All initial details of the workspace group (workspaces, outputs) will be
+ sent immediately after this event via the corresponding events in
+ zext_workspace_group_handle_v1.
+
+
+
+
+
+
+ The client must send this request after it has finished sending other
+ requests. The compositor must process a series of requests preceding a
+ commit request atomically.
+
+ This allows changes to the workspace properties to be seen as atomic,
+ even if they happen via multiple events, and even if they involve
+ multiple zext_workspace_handle_v1 objects, for example, deactivating one
+ workspace and activating another.
+
+
+
+
+
+ This event is sent after all changes in all workspace groups have been
+ sent.
+
+ This allows changes to one or more zext_workspace_group_handle_v1
+ properties to be seen as atomic, even if they happen via multiple
+ events. In particular, an output moving from one workspace group to
+ another sends an output_enter event and an output_leave event to the two
+ zext_workspace_group_handle_v1 objects in question. The compositor sends
+ the done event only after updating the output information in both
+ workspace groups.
+
+
+
+
+
+ This event indicates that the compositor is done sending events to the
+ zext_workspace_manager_v1. The server will destroy the object
+ immediately after sending this request, so it will become invalid and
+ the client should free any resources associated with it.
+
+
+
+
+
+ Indicates the client no longer wishes to receive events for new
+ workspace groups. However the compositor may emit further workspace
+ events, until the finished event is emitted.
+
+ The client must not send any more requests after this one.
+
+
+
+
+
+
+ A zext_workspace_group_handle_v1 object represents a a workspace group
+ that is assigned a set of outputs and contains a number of workspaces.
+
+ The set of outputs assigned to the workspace group is conveyed to the client via
+ output_enter and output_leave events, and its workspaces are conveyed with
+ workspace events.
+
+ For example, a compositor which has a set of workspaces for each output may
+ advertise a workspace group (and its workspaces) per output, whereas a compositor
+ where a workspace spans all outputs may advertise a single workspace group for all
+ outputs.
+
+
+
+
+ This event is emitted whenever an output is assigned to the workspace
+ group.
+
+
+
+
+
+
+ This event is emitted whenever an output is removed from the workspace
+ group.
+
+
+
+
+
+
+ This event is emitted whenever a new workspace has been created.
+
+ All initial details of the workspace (name, coordinates, state) will
+ be sent immediately after this event via the corresponding events in
+ zext_workspace_handle_v1.
+
+
+
+
+
+
+ This event means the zext_workspace_group_handle_v1 has been destroyed.
+ It is guaranteed there won't be any more events for this
+ zext_workspace_group_handle_v1. The zext_workspace_group_handle_v1 becomes
+ inert so any requests will be ignored except the destroy request.
+
+ The compositor must remove all workspaces belonging to a workspace group
+ before removing the workspace group.
+
+
+
+
+
+ Request that the compositor create a new workspace with the given name.
+
+ There is no guarantee that the compositor will create a new workspace,
+ or that the created workspace will have the provided name.
+
+
+
+
+
+
+ Destroys the zext_workspace_handle_v1 object.
+
+ This request should be called either when the client does not want to
+ use the workspace object any more or after the remove event to finalize
+ the destruction of the object.
+
+
+
+
+
+
+ A zext_workspace_handle_v1 object represents a a workspace that handles a
+ group of surfaces.
+
+ Each workspace has a name, conveyed to the client with the name event; a
+ list of states, conveyed to the client with the state event; and
+ optionally a set of coordinates, conveyed to the client with the
+ coordinates event. The client may request that the compositor activate or
+ deactivate the workspace.
+
+ Each workspace can belong to only a single workspace group.
+ Depepending on the compositor policy, there might be workspaces with
+ the same name in different workspace groups, but these workspaces are still
+ separate (e.g. one of them might be active while the other is not).
+
+
+
+
+ This event is emitted immediately after the zext_workspace_handle_v1 is
+ created and whenever the name of the workspace changes.
+
+
+
+
+
+
+ This event is used to organize workspaces into an N-dimensional grid
+ within a workspace group, and if supported, is emitted immediately after
+ the zext_workspace_handle_v1 is created and whenever the coordinates of
+ the workspace change. Compositors may not send this event if they do not
+ conceptually arrange workspaces in this way. If compositors simply
+ number workspaces, without any geometric interpretation, they may send
+ 1D coordinates, which clients should not interpret as implying any
+ geometry. Sending an empty array means that the compositor no longer
+ orders the workspace geometrically.
+
+ Coordinates have an arbitrary number of dimensions N with an uint32
+ position along each dimension. By convention if N > 1, the first
+ dimension is X, the second Y, the third Z, and so on. The compositor may
+ chose to utilize these events for a more novel workspace layout
+ convention, however. No guarantee is made about the grid being filled or
+ bounded; there may be a workspace at coordinate 1 and another at
+ coordinate 1000 and none in between. Within a workspace group, however,
+ workspaces must have unique coordinates of equal dimensionality.
+
+
+
+
+
+
+ This event is emitted immediately after the zext_workspace_handle_v1 is
+ created and each time the workspace state changes, either because of a
+ compositor action or because of a request in this protocol.
+
+
+
+
+
+
+ The different states that a workspace can have.
+
+
+
+
+
+
+ The workspace is not visible in its workspace group, and clients
+ attempting to visualize the compositor workspace state should not
+ display such workspaces.
+
+
+
+
+
+
+ This event means the zext_workspace_handle_v1 has been destroyed. It is
+ guaranteed there won't be any more events for this
+ zext_workspace_handle_v1. The zext_workspace_handle_v1 becomes inert so
+ any requests will be ignored except the destroy request.
+
+
+
+
+
+ Destroys the zext_workspace_handle_v1 object.
+
+ This request should be called either when the client does not want to
+ use the workspace object any more or after the remove event to finalize
+ the destruction of the object.
+
+
+
+
+
+ Request that this workspace be activated.
+
+ There is no guarantee the workspace will be actually activated, and
+ behaviour may be compositor-dependent. For example, activating a
+ workspace may or may not deactivate all other workspaces in the same
+ group.
+
+
+
+
+
+ Request that this workspace be deactivated.
+
+ There is no guarantee the workspace will be actually deactivated.
+
+
+
+
+
+ Request that this workspace be removed.
+
+ There is no guarantee the workspace will be actually removed.
+
+
+
+
diff --git a/applets/cosmic-applet-workspaces/src/wayland.rs b/applets/cosmic-applet-workspaces/src/wayland.rs
index 5af6e35e..94720e84 100644
--- a/applets/cosmic-applet-workspaces/src/wayland.rs
+++ b/applets/cosmic-applet-workspaces/src/wayland.rs
@@ -1,68 +1,67 @@
use crate::utils::{Activate, Workspace};
use std::{
- num::ParseIntError,
- os::unix::prelude::RawFd,
- sync::{Arc, Mutex},
+ os::unix::{net::UnixStream}, env, path::PathBuf,
};
+use wayland_client::{ConnectError, DelegateDispatch, protocol::wl_registry};
use tokio::sync::mpsc;
-use wayland_client::{protocol::wl_registry, Display, GlobalManager};
-use generated::client::{zext_workspace_manager_v1, zext_workspace_group_handle_v1, zext_workspace_handle_v1};
-use sctk::environment::{SimpleGlobal, Environment};
-use sctk::environment;
+
+use wayland_client::{
+ Connection, Dispatch, QueueHandle,
+};
+
+/// Generated protocol definitions
mod generated {
- // The generated code tends to trigger a lot of warnings
- // so we isolate it into a very permissive module
- #![allow(dead_code, non_camel_case_types, unused_unsafe, unused_variables)]
- #![allow(non_upper_case_globals, non_snake_case, unused_imports)]
+ #![allow(dead_code,non_camel_case_types,unused_unsafe,unused_variables)]
+ #![allow(non_upper_case_globals,non_snake_case,unused_imports)]
+ #![allow(missing_docs, clippy::all)]
pub mod client {
- // These imports are used by the generated code
- pub(crate) use wayland_commons::map::{Object, ObjectMetadata};
- pub(crate) use wayland_commons::smallvec;
- pub(crate) use wayland_commons::wire::{Argument, ArgumentType, Message, MessageDesc};
- pub(crate) use wayland_commons::{Interface, MessageGroup};
- pub(crate) use wayland_client::protocol::wl_output;
- pub(crate) use wayland_client::sys;
- pub(crate) use wayland_client::{AnonymousObject, Main, Proxy, ProxyMap};
- include!(concat!(env!("OUT_DIR"), "/ext_workspace.rs"));
+ //! Client-side API of this protocol
+ use wayland_client;
+ use wayland_client::protocol::*;
+
+ pub mod __interfaces {
+ use wayland_client::protocol::__interfaces::*;
+ wayland_scanner::generate_interfaces!("src/ext-workspace-unstable-v1.xml");
+ }
+ use self::__interfaces::*;
+
+ wayland_scanner::generate_client_code!("src/ext-workspace-unstable-v1.xml");
}
}
-#[derive(Debug)]
-struct State {
- workspace_manager: SimpleGlobal,
-}
-
-environment!(State,
- singles = [
- zext_workspace_manager_v1::ZextWorkspaceManagerV1 => workspace_manager,
- ],
- multis = []
-);
+use generated::client::zext_workspace_manager_v1;
pub fn spawn_workspaces(tx: mpsc::Sender>) -> mpsc::Sender {
let (workspaces_tx, mut workspaces_rx) = mpsc::channel(100);
- if let Ok(display) = std::env::var("HOST_WAYLAND_DISPLAY")
+ if let Ok(Ok(conn)) = std::env::var("HOST_WAYLAND_DISPLAY")
.map_err(anyhow::Error::msg)
- .and_then(|fd| Display::connect_to_name(fd).map_err(anyhow::Error::msg))
+ .map(|fd| {
+ let mut socket_path = env::var_os("XDG_RUNTIME_DIR")
+ .map(Into::::into)
+ .ok_or(ConnectError::NoCompositor)?;
+ socket_path.push(env::var_os("WAYLAND_DISPLAY").ok_or(ConnectError::NoCompositor)?);
+
+ Ok(UnixStream::connect(socket_path).map_err(|_| ConnectError::NoCompositor)?)
+ })
+ .and_then(|s| s.map(|s| Connection::from_socket(s).map_err(anyhow::Error::msg)))
{
std::thread::spawn(move || {
- let mut event_queue = display.create_event_queue();
- let attached_display = display.attach(event_queue.token());
- let env = State {
- workspace_manager: SimpleGlobal::new(),
+ let mut event_queue= conn.new_event_queue::();
+ let qhandle = event_queue.handle();
+
+ let display = conn.display();
+ display.get_registry(&qhandle, ()).unwrap();
+
+ let mut state = State {
+ workspace_manager: None,
+ tx,
+ running: true,
};
- let env = Environment::new(&attached_display, &mut event_queue, env).expect("Failed to create environment");
-
- let workspace_manager = env.require_global::();
- dbg!(workspace_manager);
- // let globals = GlobalManager::new(&attached_display);
- // let _ = event_queue.sync_roundtrip(&mut (), |_, _, _| unreachable!());
-
- // println!("Globals: ");
- // for (name, interface, version) in globals.list() {
- // println!("{}: {} (version {})", name, interface, version);
- // }
+
+ while state.running {
+ event_queue.blocking_dispatch(&mut state).unwrap();
+ }
});
} else {
eprintln!("ENV variable HOST_WAYLAND_DISPLAY is missing. Exiting...");
@@ -74,5 +73,44 @@ pub fn spawn_workspaces(tx: mpsc::Sender>) -> mpsc::Sender>,
+ workspace_manager: Option,
+}
+impl Dispatch for State {
+ fn event(
+ &mut self,
+ registry: &wl_registry::WlRegistry,
+ event: wl_registry::Event,
+ _: &(),
+ _: &Connection,
+ qh: &QueueHandle,
+ ) {
+ if let wl_registry::Event::Global { name, interface, version } = event {
+ println!("[{}] {} (v{})", name, interface, version);
+ match &interface[..] {
+ "zext_workspace_manager_v1" => {
+ println!("binding to workspace manager");
+ registry.bind::(name, 1, qh, ()).unwrap();
+ },
+ _ => {}
+ }
+ }
+ }
+}
+impl Dispatch for State {
+ fn event(
+ &mut self,
+ _: &zext_workspace_manager_v1::ZextWorkspaceManagerV1,
+ _: zext_workspace_manager_v1::Event,
+ _: &(),
+ _: &Connection,
+ _: &QueueHandle,
+ ) {
+ todo!()
+ // wl_compositor has no event
+ }
+}