fix: apply default behavior to workspaces which never had a toplevel
This commit is contained in:
parent
5b2bc8eac1
commit
5ae7a29dc7
3 changed files with 110 additions and 12 deletions
|
|
@ -9,15 +9,22 @@ use cctk::{
|
|||
reexports::{calloop, calloop_wayland_source::WaylandSource, client as wayland_client},
|
||||
registry::{ProvidesRegistryState, RegistryState},
|
||||
},
|
||||
toplevel_info::{ToplevelInfoHandler, ToplevelInfoState},
|
||||
wayland_client::WEnum,
|
||||
workspace::{WorkspaceHandler, WorkspaceState},
|
||||
};
|
||||
use cosmic::iced::futures;
|
||||
use cosmic_protocols::workspace::v1::client::zcosmic_workspace_handle_v1::{self, TilingState};
|
||||
use cosmic_protocols::{
|
||||
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
||||
workspace::v1::client::zcosmic_workspace_handle_v1::{self, TilingState},
|
||||
};
|
||||
use futures::{channel::mpsc, executor::block_on, SinkExt};
|
||||
use std::os::{
|
||||
fd::{FromRawFd, RawFd},
|
||||
unix::net::UnixStream,
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
os::{
|
||||
fd::{FromRawFd, RawFd},
|
||||
unix::net::UnixStream,
|
||||
},
|
||||
};
|
||||
use tracing::error;
|
||||
use wayland_client::{
|
||||
|
|
@ -26,7 +33,13 @@ use wayland_client::{
|
|||
};
|
||||
use wayland_client::{Connection, QueueHandle};
|
||||
|
||||
pub fn spawn_workspaces(tx: mpsc::Sender<TilingState>) -> SyncSender<TilingState> {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AppRequest {
|
||||
TilingState(TilingState),
|
||||
DefaultBehavior(TilingState),
|
||||
}
|
||||
|
||||
pub fn spawn_workspaces(tx: mpsc::Sender<TilingState>) -> SyncSender<AppRequest> {
|
||||
let (workspaces_tx, workspaces_rx) = calloop::channel::sync_channel(100);
|
||||
|
||||
let socket = std::env::var("X_PRIVILEGED_WAYLAND_SOCKET")
|
||||
|
|
@ -64,6 +77,8 @@ pub fn spawn_workspaces(tx: mpsc::Sender<TilingState>) -> SyncSender<TilingState
|
|||
output_state: OutputState::new(&globals, &qhandle),
|
||||
configured_output,
|
||||
workspace_state: WorkspaceState::new(®istry_state, &qhandle),
|
||||
toplevel_info_state: ToplevelInfoState::new(®istry_state, &qhandle),
|
||||
workspaces_with_previous_toplevel: HashSet::new(),
|
||||
registry_state,
|
||||
expected_output: None,
|
||||
tx,
|
||||
|
|
@ -73,7 +88,7 @@ pub fn spawn_workspaces(tx: mpsc::Sender<TilingState>) -> SyncSender<TilingState
|
|||
let loop_handle = event_loop.handle();
|
||||
loop_handle
|
||||
.insert_source(workspaces_rx, |e, _, state| match e {
|
||||
Event::Msg(autotile) => {
|
||||
Event::Msg(AppRequest::TilingState(autotile)) => {
|
||||
if let Some(w) =
|
||||
state
|
||||
.workspace_state
|
||||
|
|
@ -101,6 +116,25 @@ pub fn spawn_workspaces(tx: mpsc::Sender<TilingState>) -> SyncSender<TilingState
|
|||
.commit();
|
||||
}
|
||||
}
|
||||
Event::Msg(AppRequest::DefaultBehavior(tiling)) => {
|
||||
for w in state
|
||||
.workspace_state
|
||||
.workspace_groups()
|
||||
.iter()
|
||||
.flat_map(|g| g.workspaces.iter())
|
||||
.filter(|w| {
|
||||
!state.workspaces_with_previous_toplevel.contains(&w.handle)
|
||||
})
|
||||
{
|
||||
w.handle.set_tiling_state(tiling);
|
||||
}
|
||||
state
|
||||
.workspace_state
|
||||
.workspace_manager()
|
||||
.get()
|
||||
.unwrap()
|
||||
.commit();
|
||||
}
|
||||
Event::Closed => {
|
||||
if let Ok(workspace_manager) =
|
||||
state.workspace_state.workspace_manager().get()
|
||||
|
|
@ -134,6 +168,9 @@ pub struct State {
|
|||
output_state: OutputState,
|
||||
registry_state: RegistryState,
|
||||
workspace_state: WorkspaceState,
|
||||
toplevel_info_state: ToplevelInfoState,
|
||||
workspaces_with_previous_toplevel:
|
||||
HashSet<zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1>,
|
||||
have_workspaces: bool,
|
||||
}
|
||||
|
||||
|
|
@ -228,6 +265,53 @@ impl WorkspaceHandler for State {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToplevelInfoHandler for State {
|
||||
fn toplevel_info_state(&mut self) -> &mut ToplevelInfoState {
|
||||
&mut self.toplevel_info_state
|
||||
}
|
||||
|
||||
fn new_toplevel(
|
||||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||
) {
|
||||
let Some(w) = self
|
||||
.toplevel_info_state
|
||||
.info(&toplevel)
|
||||
.map(|t| t.workspace.clone())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
self.workspaces_with_previous_toplevel.extend(w);
|
||||
}
|
||||
|
||||
fn update_toplevel(
|
||||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||
) {
|
||||
let Some(w) = self
|
||||
.toplevel_info_state
|
||||
.info(&toplevel)
|
||||
.map(|t| t.workspace.clone())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
self.workspaces_with_previous_toplevel.extend(w);
|
||||
}
|
||||
|
||||
fn toplevel_closed(
|
||||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
_toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
cctk::delegate_toplevel_info!(State);
|
||||
cctk::delegate_workspace!(State);
|
||||
sctk::delegate_output!(State);
|
||||
sctk::delegate_registry!(State);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::wayland::{self};
|
||||
use crate::wayland::{self, AppRequest};
|
||||
use cctk::sctk::reexports::calloop::channel::SyncSender;
|
||||
use cosmic::iced::{
|
||||
self,
|
||||
|
|
@ -18,7 +18,7 @@ pub static WAYLAND_RX: Lazy<Mutex<Option<mpsc::Receiver<TilingState>>>> =
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum WorkspacesUpdate {
|
||||
State(TilingState),
|
||||
Started(SyncSender<TilingState>),
|
||||
Started(SyncSender<AppRequest>),
|
||||
Errored,
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ pub enum State {
|
|||
|
||||
pub struct WorkspacesWatcher {
|
||||
rx: mpsc::Receiver<TilingState>,
|
||||
tx: SyncSender<TilingState>,
|
||||
tx: SyncSender<AppRequest>,
|
||||
}
|
||||
|
||||
impl WorkspacesWatcher {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::wayland::AppRequest;
|
||||
use crate::wayland_subscription::WorkspacesUpdate;
|
||||
use crate::{fl, wayland_subscription};
|
||||
use cctk::sctk::reexports::calloop::channel::SyncSender;
|
||||
|
|
@ -36,7 +37,7 @@ pub struct Window {
|
|||
new_workspace_entity: Entity,
|
||||
/// may not match the config value if behavior is per-workspace
|
||||
autotiled: bool,
|
||||
workspace_tx: Option<SyncSender<TilingState>>,
|
||||
workspace_tx: Option<SyncSender<AppRequest>>,
|
||||
tile_windows: id::Toggler,
|
||||
active_hint: id::Toggler,
|
||||
}
|
||||
|
|
@ -199,7 +200,7 @@ impl cosmic::Application for Window {
|
|||
TilingState::FloatingOnly
|
||||
};
|
||||
|
||||
if let Err(err) = tx.send(state) {
|
||||
if let Err(err) = tx.send(AppRequest::TilingState(state)) {
|
||||
error!("Failed to send the tiling state update. {err:?}")
|
||||
}
|
||||
}
|
||||
|
|
@ -241,6 +242,19 @@ impl cosmic::Application for Window {
|
|||
self.new_workspace_behavior_model.activate(e);
|
||||
// set the config autotile behavior
|
||||
let helper = self.config_helper.clone();
|
||||
|
||||
if let Some(tx) = self.workspace_tx.as_ref() {
|
||||
let state = if autotile_new {
|
||||
TilingState::TilingEnabled
|
||||
} else {
|
||||
TilingState::FloatingOnly
|
||||
};
|
||||
|
||||
if let Err(err) = tx.send(AppRequest::DefaultBehavior(state)) {
|
||||
error!("Failed to send the tiling state update. {err:?}")
|
||||
}
|
||||
}
|
||||
|
||||
thread::spawn(move || {
|
||||
if let Err(err) = helper.set("autotile", autotile_new) {
|
||||
error!(?err, "Failed to set autotile {autotile_new:?}");
|
||||
|
|
@ -260,7 +274,7 @@ impl cosmic::Application for Window {
|
|||
}
|
||||
|
||||
fn view_window(&self, _id: Id) -> Element<Self::Message> {
|
||||
let mut new_workspace_behavior_button =
|
||||
let new_workspace_behavior_button =
|
||||
segmented_control::horizontal(&self.new_workspace_behavior_model)
|
||||
.on_activate(Message::NewWorkspace);
|
||||
let content_list = column![
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue