diff --git a/Cargo.lock b/Cargo.lock
index 5a8ece17..ed85b549 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -325,13 +325,11 @@ dependencies = [
"gtk4",
"libcosmic-widgets",
"libpulse-binding",
- "mpris2-zbus",
"once_cell",
"pulsectl-rs",
"relm4-macros 0.4.4",
"tokio",
"tracker",
- "zbus",
]
[[package]]
@@ -393,6 +391,26 @@ dependencies = [
"zvariant",
]
+[[package]]
+name = "cosmic-applet-workspaces"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "cascade",
+ "cosmic-panel-config",
+ "gio",
+ "gtk4",
+ "i18n-embed",
+ "i18n-embed-fl",
+ "once_cell",
+ "pretty_env_logger",
+ "rust-embed",
+ "tokio",
+ "wayland-client",
+ "wayland-commons",
+ "wayland-scanner",
+]
+
[[package]]
name = "cosmic-dbus-networkmanager"
version = "0.1.0"
@@ -1632,18 +1650,6 @@ dependencies = [
"windows-sys",
]
-[[package]]
-name = "mpris2-zbus"
-version = "0.1.0"
-source = "git+https://github.com/pop-os/mpris2-zbus#bcc8481ea7ccfc08aa870f28272d9093db3b1ba9"
-dependencies = [
- "serde",
- "thiserror",
- "time 0.3.9",
- "zbus",
- "zvariant",
-]
-
[[package]]
name = "nanorand"
version = "0.7.0"
diff --git a/Cargo.toml b/Cargo.toml
index cfa413b3..bee4d6a5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,6 +4,7 @@ members = [
"applets/cosmic-applet-graphics",
"applets/cosmic-applet-network",
"applets/cosmic-applet-power",
+ "applets/cosmic-applet-workspaces",
"applets/cosmic-applet-status-area",
"applets/cosmic-app-list",
"applets/cosmic-panel-button",
diff --git a/applets/cosmic-applet-workspaces/Cargo.toml b/applets/cosmic-applet-workspaces/Cargo.toml
index 3f9ea555..c0f1291f 100644
--- a/applets/cosmic-applet-workspaces/Cargo.toml
+++ b/applets/cosmic-applet-workspaces/Cargo.toml
@@ -17,7 +17,9 @@ 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"
[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 7c42fb5e..040a9eef 100644
--- a/applets/cosmic-applet-workspaces/build.rs
+++ b/applets/cosmic-applet-workspaces/build.rs
@@ -1,7 +1,30 @@
+extern crate wayland_scanner;
+
+use std::{env, path::PathBuf, process::Command};
+use wayland_scanner::{generate_code, Side};
+
fn main() {
+ if let Some(output) = Command::new("git")
+ .args(&["rev-parse", "HEAD"])
+ .output()
+ .ok()
+{
+ let git_hash = String::from_utf8(output.stdout).unwrap();
+ println!("cargo:rustc-env=GIT_HASH={}", git_hash);
+}
gio::compile_resources(
"data/resources",
"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 drm_protocol_file = "data/resources/wayland-drm.xml";
+ 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,
+ );
}
diff --git a/applets/cosmic-applet-workspaces/data/com.system76.CosmicAppletWorkspaces.desktop b/applets/cosmic-applet-workspaces/data/com.system76.CosmicAppletWorkspaces.desktop
index 7b981b33..ac83c2b4 100644
--- a/applets/cosmic-applet-workspaces/data/com.system76.CosmicAppletWorkspaces.desktop
+++ b/applets/cosmic-applet-workspaces/data/com.system76.CosmicAppletWorkspaces.desktop
@@ -1,13 +1,12 @@
[Desktop Entry]
-Name=Cosmic Applet Power
+Name=Cosmic Applet Workspaces
Comment=Write a GTK + Rust application
Type=Application
-Exec=cosmic-applet-power
+Exec=cosmic-applet-workspaces
Terminal=false
Categories=GNOME;GTK;
Keywords=Gnome;GTK;
-# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
-Icon=com.system76.CosmicAppletPower.svg
+Icon=com.system76.CosmicAppletWorkspaces.svg
StartupNotify=true
NoDisplay=true
-HostWaylandSocket=true
+HostWaylandDisplay=true
diff --git a/applets/cosmic-applet-workspaces/data/resources/ext-workspace-unstable-v1.xml b/applets/cosmic-applet-workspaces/data/resources/ext-workspace-unstable-v1.xml
new file mode 100644
index 00000000..24410b62
--- /dev/null
+++ b/applets/cosmic-applet-workspaces/data/resources/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/data/resources/resources.gresource.xml b/applets/cosmic-applet-workspaces/data/resources/resources.gresource.xml
index 2cf0970f..8b69c0d6 100644
--- a/applets/cosmic-applet-workspaces/data/resources/resources.gresource.xml
+++ b/applets/cosmic-applet-workspaces/data/resources/resources.gresource.xml
@@ -1,6 +1,6 @@
-
-
+
+ style.css
diff --git a/applets/cosmic-applet-workspaces/src/main.rs b/applets/cosmic-applet-workspaces/src/main.rs
index df05758b..21eb8dec 100644
--- a/applets/cosmic-applet-workspaces/src/main.rs
+++ b/applets/cosmic-applet-workspaces/src/main.rs
@@ -1,22 +1,28 @@
// SPDX-License-Identifier: MPL-2.0-only
-use gtk4::{gdk::Display, gio::{self, ApplicationFlags}, glib, prelude::*, CssProvider, StyleContext};
+use gtk4::{
+ gdk::Display,
+ gio::{self, ApplicationFlags},
+ glib,
+ prelude::*,
+ CssProvider, StyleContext,
+};
use once_cell::sync::OnceCell;
-use window::CosmicWorkspacesWindow;
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc;
-use utils::{Event, BoxedWorkspaceList};
+use utils::{Activate, Workspace};
+use window::CosmicWorkspacesWindow;
+mod localize;
+mod utils;
+mod wayland;
mod window;
mod workspace_button;
mod workspace_list;
-mod wayland;
-mod localize;
-mod utils;
mod workspace_object;
const ID: &str = "com.system76.CosmicAppletWorkspaces";
-static TX: OnceCell> = OnceCell::new();
+static TX: OnceCell> = OnceCell::new();
pub fn localize() {
let localizer = crate::localize::localizer();
@@ -29,7 +35,7 @@ pub fn localize() {
fn load_css() {
let provider = CssProvider::new();
- provider.load_from_resource("/com.system76.CosmicAppletWorkspaces/style.css");
+ provider.load_from_resource("/com/System76/CosmicAppletWorkspaces/style.css");
StyleContext::add_provider_for_display(
&Display::default().unwrap(),
@@ -50,24 +56,16 @@ fn main() {
app.connect_activate(|app| {
load_css();
- let (tx, mut rx) = mpsc::channel(100);
+ let (tx, mut rx) = mpsc::channel::>(100);
- let window = CosmicWorkspacesWindow::new(app, tx.clone());
+ let wayland_tx = wayland::spawn_workspaces(tx.clone());
+ let window = CosmicWorkspacesWindow::new(app);
- let workspace_list = Arc::new(Mutex::new(Vec::::new()));
-
- TX.set(tx.clone()).unwrap();
+ TX.set(wayland_tx).unwrap();
let _ = glib::MainContext::default().spawn_local(async move {
- while let Some(event) = rx.recv().await {
- match event {
- Event::Activate(_) => {
- // TODO activate the selected workspace
- }
- Event::WorkspaceList => {
- // TODO update the model with the new workspace list
- }
- }
+ while let Some(workspace_list) = rx.recv().await {
+ // TODO update the model with the new workspace list
}
});
window.show();
diff --git a/applets/cosmic-applet-workspaces/src/utils.rs b/applets/cosmic-applet-workspaces/src/utils.rs
index 4d27e5e9..7dd7f3f8 100644
--- a/applets/cosmic-applet-workspaces/src/utils.rs
+++ b/applets/cosmic-applet-workspaces/src/utils.rs
@@ -5,26 +5,13 @@ use std::path::PathBuf;
use gtk4::glib;
use std::future::Future;
-#[derive(Debug)]
-pub enum Event {
- WorkspaceList,
- Activate(u32),
-}
-
+pub type Activate = u32;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Workspace {
pub(crate) id: u32,
pub(crate) active: bool,
}
-#[derive(Clone, Debug, Default, glib::Boxed)]
-#[boxed_type(name = "BoxedWorkspace")]
-pub struct BoxedWorkspace(pub Option);
-
-#[derive(Clone, Debug, Default, glib::Boxed)]
-#[boxed_type(name = "BoxedWorkspaceList")]
-pub struct BoxedWorkspaceList(pub Vec);
-
pub fn data_path() -> PathBuf {
let mut path = glib::user_data_dir();
path.push(crate::ID);
diff --git a/applets/cosmic-applet-workspaces/src/wayland.rs b/applets/cosmic-applet-workspaces/src/wayland.rs
index e69de29b..0bced8dc 100644
--- a/applets/cosmic-applet-workspaces/src/wayland.rs
+++ b/applets/cosmic-applet-workspaces/src/wayland.rs
@@ -0,0 +1,52 @@
+use crate::utils::{Activate, Workspace};
+use std::{
+ num::ParseIntError,
+ os::unix::prelude::RawFd,
+ sync::{Arc, Mutex},
+};
+use tokio::sync::mpsc;
+use wayland_client::{protocol::wl_registry, Display, GlobalManager};
+
+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)]
+
+ 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"));
+ }
+}
+
+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")
+ .map_err(anyhow::Error::msg)
+ .and_then(|fd| Display::connect_to_name(fd).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 globals = GlobalManager::new(&attached_display);
+ dbg!(event_queue.sync_roundtrip(&mut (), |_, _, _| unreachable!()));
+
+ println!("Globals: ");
+ for (name, interface, version) in globals.list() {
+ println!("{}: {} (version {})", name, interface, version);
+ }
+ });
+ } else {
+ eprintln!("ENV variable HOST_WAYLAND_SOCKET is missing. Exiting...");
+ std::process::exit(1);
+ }
+
+ workspaces_tx
+}
diff --git a/applets/cosmic-applet-workspaces/src/window/imp.rs b/applets/cosmic-applet-workspaces/src/window/imp.rs
index d614237c..17364349 100644
--- a/applets/cosmic-applet-workspaces/src/window/imp.rs
+++ b/applets/cosmic-applet-workspaces/src/window/imp.rs
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MPL-2.0-only
+use crate::workspace_list::WorkspaceList;
use gtk4::{glib, subclass::prelude::*};
use once_cell::sync::OnceCell;
-use crate::{workspace_list::WorkspaceList};
// Object holding the state
#[derive(Default)]
diff --git a/applets/cosmic-applet-workspaces/src/window/mod.rs b/applets/cosmic-applet-workspaces/src/window/mod.rs
index 585a1e87..4b0035b7 100644
--- a/applets/cosmic-applet-workspaces/src/window/mod.rs
+++ b/applets/cosmic-applet-workspaces/src/window/mod.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0-only
-use crate::{fl, utils::Event, workspace_list::WorkspaceList};
+use crate::{fl, utils::Activate, workspace_list::WorkspaceList};
use cascade::cascade;
use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::{
@@ -21,7 +21,7 @@ glib::wrapper! {
}
impl CosmicWorkspacesWindow {
- pub fn new(app: >k4::Application, tx: mpsc::Sender) -> Self {
+ pub fn new(app: >k4::Application) -> Self {
let self_: Self = Object::new(&[("application", app)])
.expect("Failed to create `CosmicWorkspacesWindow`.");
let imp = imp::CosmicWorkspacesWindow::from_instance(&self_);
@@ -37,7 +37,7 @@ impl CosmicWorkspacesWindow {
};
let config = CosmicPanelConfig::load_from_env().unwrap_or_default();
- let app_list = WorkspaceList::new(tx, config);
+ let app_list = WorkspaceList::new(config);
self_.set_child(Some(&app_list));
imp.inner.set(app_list).unwrap();
diff --git a/applets/cosmic-applet-workspaces/src/workspace_button/imp.rs b/applets/cosmic-applet-workspaces/src/workspace_button/imp.rs
index 8d462c6c..483cd249 100644
--- a/applets/cosmic-applet-workspaces/src/workspace_button/imp.rs
+++ b/applets/cosmic-applet-workspaces/src/workspace_button/imp.rs
@@ -1,13 +1,12 @@
-use std::{rc::Rc, cell::RefCell};
-use gtk4::{ToggleButton, glib, subclass::prelude::*};
-use tokio::sync::mpsc;
+use crate::Activate;
+use gtk4::{glib, subclass::prelude::*, ToggleButton};
use once_cell::sync::OnceCell;
-use crate::Event;
+use std::{cell::RefCell, rc::Rc};
+use tokio::sync::mpsc;
// Object holding the state
#[derive(Default)]
pub struct WorkspaceButton {
- pub tx: Rc>>,
pub button: Rc>,
}
@@ -26,4 +25,4 @@ impl ObjectImpl for WorkspaceButton {}
impl WidgetImpl for WorkspaceButton {}
// Trait shared by all buttons
-impl BoxImpl for WorkspaceButton {}
\ No newline at end of file
+impl BoxImpl for WorkspaceButton {}
diff --git a/applets/cosmic-applet-workspaces/src/workspace_button/mod.rs b/applets/cosmic-applet-workspaces/src/workspace_button/mod.rs
index bf5a4ab8..22dea99b 100644
--- a/applets/cosmic-applet-workspaces/src/workspace_button/mod.rs
+++ b/applets/cosmic-applet-workspaces/src/workspace_button/mod.rs
@@ -1,9 +1,8 @@
mod imp;
+use crate::{workspace_object::WorkspaceObject, Activate, TX};
use glib::Object;
use gtk4::{glib, prelude::*, subclass::prelude::*, ToggleButton};
-use tokio::sync::mpsc;
-use crate::{Event, workspace_object::WorkspaceObject};
glib::wrapper! {
pub struct WorkspaceButton(ObjectSubclass)
@@ -12,16 +11,15 @@ glib::wrapper! {
}
impl WorkspaceButton {
- pub fn new(tx: mpsc::Sender) -> Self {
+ pub fn new() -> Self {
let self_ = Object::new(&[]).expect("Failed to create `WorkspaceButton`.");
let imp = imp::WorkspaceButton::from_instance(&self_);
- imp.tx.set(tx).unwrap();
let tb = ToggleButton::with_label("");
self_.append(&tb);
imp.button.replace(tb);
-
+
self_
}
@@ -34,9 +32,9 @@ impl WorkspaceButton {
let new_button = ToggleButton::with_label(&format!("{}", id));
new_button.set_active(obj.active());
self.append(&new_button);
- new_button.connect_clicked(glib::clone!(@weak imp.tx as tx => move |_| {
- let _ = tx.get().unwrap().send(Event::Activate(id));
- }));
+ new_button.connect_clicked(move |_| {
+ let _ = TX.get().unwrap().send(id);
+ });
imp.button.replace(new_button);
}
diff --git a/applets/cosmic-applet-workspaces/src/workspace_list/imp.rs b/applets/cosmic-applet-workspaces/src/workspace_list/imp.rs
index e70a1a4b..634c1714 100644
--- a/applets/cosmic-applet-workspaces/src/workspace_list/imp.rs
+++ b/applets/cosmic-applet-workspaces/src/workspace_list/imp.rs
@@ -1,20 +1,19 @@
// SPDX-License-Identifier: MPL-2.0-only
-use cosmic_panel_config::config::{CosmicPanelConfig};
+use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::subclass::prelude::*;
use gtk4::{gio, glib};
use gtk4::{Box, ListView};
-use tokio::sync::mpsc;
use once_cell::sync::OnceCell;
+use tokio::sync::mpsc;
-use crate::utils::Event;
+use crate::utils::Activate;
#[derive(Debug, Default)]
pub struct WorkspaceList {
pub list_view: OnceCell,
pub model: OnceCell,
- pub tx: OnceCell>,
- pub config: OnceCell
+ pub config: OnceCell,
}
#[glib::object_subclass]
diff --git a/applets/cosmic-applet-workspaces/src/workspace_list/mod.rs b/applets/cosmic-applet-workspaces/src/workspace_list/mod.rs
index 5cd6fe35..e7c031ef 100644
--- a/applets/cosmic-applet-workspaces/src/workspace_list/mod.rs
+++ b/applets/cosmic-applet-workspaces/src/workspace_list/mod.rs
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: MPL-2.0-only
-use crate::utils::{Event, BoxedWorkspace};
+use crate::utils::Activate;
use crate::workspace_button::WorkspaceButton;
use crate::workspace_object::WorkspaceObject;
use cascade::cascade;
-use cosmic_panel_config::config::{CosmicPanelConfig};
-use gtk4::{glib, gio, prelude::*, subclass::prelude::*};
+use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::ListView;
use gtk4::Orientation;
use gtk4::SignalListItemFactory;
+use gtk4::{gio, glib, prelude::*, subclass::prelude::*};
use tokio::sync::mpsc::Sender;
mod imp;
@@ -20,10 +20,9 @@ glib::wrapper! {
}
impl WorkspaceList {
- pub fn new(tx: Sender, config: CosmicPanelConfig) -> Self {
+ pub fn new(config: CosmicPanelConfig) -> Self {
let self_: WorkspaceList = glib::Object::new(&[]).expect("Failed to create WorkspaceList");
let imp = imp::WorkspaceList::from_instance(&self_);
- imp.tx.set(tx).unwrap();
imp.config.set(config).unwrap();
self_.layout();
//dnd behavior is different for each type, as well as the data in the model
@@ -51,7 +50,7 @@ impl WorkspaceList {
fn setup_model(&self) {
let imp = imp::WorkspaceList::from_instance(self);
- let model = gio::ListStore::new(BoxedWorkspace::static_type());
+ let model = gio::ListStore::new(WorkspaceObject::static_type());
let selection_model = gtk4::NoSelection::new(Some(&model));
@@ -65,28 +64,24 @@ impl WorkspaceList {
let imp = imp::WorkspaceList::from_instance(self);
let factory = SignalListItemFactory::new();
let model = imp.model.get().expect("Failed to get saved app model.");
- let tx = imp.tx.get().unwrap().clone();
let icon_size = imp.config.get().unwrap().get_applet_icon_size();
- factory.connect_setup(
- glib::clone!(@weak model => move |_, list_item| {
- let workspace_button = WorkspaceButton::new(tx.clone());
- list_item.set_child(Some(&workspace_button));
- }),
- );
+ factory.connect_setup(glib::clone!(@weak model => move |_, list_item| {
+ let workspace_button = WorkspaceButton::new();
+ list_item.set_child(Some(&workspace_button));
+ }));
factory.connect_bind(|_, list_item| {
- let workspace_object = list_item
- .item()
- .expect("The item has to exist.")
- .downcast::()
- .expect("The item has to be a `DockObject`");
- let workspace_button = list_item
- .child()
- .expect("The list item child needs to exist.")
- .downcast::()
- .expect("The list item type needs to be `DockItem`");
- workspace_button.set_workspace_object(&workspace_object);
- },
- );
+ let workspace_object = list_item
+ .item()
+ .expect("The item has to exist.")
+ .downcast::()
+ .expect("The item has to be a `DockObject`");
+ let workspace_button = list_item
+ .child()
+ .expect("The list item child needs to exist.")
+ .downcast::()
+ .expect("The list item type needs to be `DockItem`");
+ workspace_button.set_workspace_object(&workspace_object);
+ });
// Set the factory of the list view
imp.list_view.get().unwrap().set_factory(Some(&factory));
}
diff --git a/applets/cosmic-applet-workspaces/src/workspace_object/imp.rs b/applets/cosmic-applet-workspaces/src/workspace_object/imp.rs
index 30ff60ca..5de4e464 100644
--- a/applets/cosmic-applet-workspaces/src/workspace_object/imp.rs
+++ b/applets/cosmic-applet-workspaces/src/workspace_object/imp.rs
@@ -53,7 +53,6 @@ impl ObjectImpl for WorkspaceObject {
false,
ParamFlags::READWRITE,
),
-
]
});
PROPERTIES.as_ref()
diff --git a/applets/cosmic-applet-workspaces/src/workspace_object/mod.rs b/applets/cosmic-applet-workspaces/src/workspace_object/mod.rs
index 5fa2f740..7b171a94 100644
--- a/applets/cosmic-applet-workspaces/src/workspace_object/mod.rs
+++ b/applets/cosmic-applet-workspaces/src/workspace_object/mod.rs
@@ -19,11 +19,11 @@ impl WorkspaceObject {
pub fn id(&self) -> u32 {
imp::WorkspaceObject::from_instance(&self).id.get()
- }
+ }
pub fn active(&self) -> bool {
imp::WorkspaceObject::from_instance(&self).active.get()
- }
+ }
}
#[derive(Clone, Debug, Default, glib::Boxed)]
diff --git a/justfile b/justfile
index 7028a576..29c7e003 100644
--- a/justfile
+++ b/justfile
@@ -18,6 +18,7 @@ audio_id := 'com.system76.CosmicAppletAudio'
graphics_id := 'com.system76.CosmicAppletGraphics'
network_id := 'com.system76.CosmicAppletNetwork'
power_id := 'com.system76.CosmicAppletPower'
+workspaces_id := 'com.system76.CosmicAppletWorkspaces'
status_area_id := 'com.system76.CosmicAppletStatusArea'
app_button_id := 'com.system76.CosmicPanelAppButton'
workspaces_button_id := 'com.system76.CosmicPanelWorkspacesButton'
@@ -54,6 +55,11 @@ install:
install -Dm0644 applets/cosmic-applet-power/data/{{power_id}}.desktop {{sharedir}}/applications/{{power_id}}.desktop
install -Dm04755 target/release/cosmic-applet-power {{bindir}}/cosmic-applet-power
+ # workspaces
+ install -Dm0644 applets/cosmic-applet-workspaces/data/icons/{{workspaces_id}}.svg {{iconsdir}}/{{workspaces_id}}.svg
+ install -Dm0644 applets/cosmic-applet-workspaces/data/{{workspaces_id}}.desktop {{sharedir}}/applications/{{workspaces_id}}.desktop
+ install -Dm04755 target/release/cosmic-applet-workspaces {{bindir}}/cosmic-applet-workspaces
+
# status area
install -Dm0644 applets/cosmic-applet-status-area/data/icons/{{status_area_id}}.svg {{iconsdir}}/{{status_area_id}}.svg
install -Dm0644 applets/cosmic-applet-status-area/data/{{status_area_id}}.desktop {{sharedir}}/applications/{{status_area_id}}.desktop