Initial support for workspace pinning and moving
Adds support for cosmic-workspace-v2 pin, unpin, move_after, and move_before requests. Both features need some work with workspaces span displays mode, so that will need more fixes later. We also want to generate a unique id for pinned workspaces to send in the ext-workspace-v1 protocol. But that isn't a strict requirement for anything. So I haven't yet fully implemented that. We'll also want to persist other things, like workspace naming when that's added. Overall, though, with separate workspaces per display, this is working pretty well.
This commit is contained in:
parent
d1f4e7b12d
commit
96e9bf3b81
14 changed files with 622 additions and 118 deletions
|
|
@ -13,7 +13,7 @@ use smithay::reexports::{
|
|||
use std::sync::Mutex;
|
||||
|
||||
use super::{
|
||||
Request, Workspace, WorkspaceCapabilities, WorkspaceData, WorkspaceGlobalData,
|
||||
Request, State, Workspace, WorkspaceCapabilities, WorkspaceData, WorkspaceGlobalData,
|
||||
WorkspaceHandler, WorkspaceManagerData, WorkspaceState,
|
||||
};
|
||||
|
||||
|
|
@ -21,6 +21,7 @@ use super::{
|
|||
pub struct CosmicWorkspaceV2DataInner {
|
||||
capabilities: Option<zcosmic_workspace_handle_v2::WorkspaceCapabilities>,
|
||||
tiling: Option<zcosmic_workspace_handle_v2::TilingState>,
|
||||
states: Option<zcosmic_workspace_handle_v2::State>,
|
||||
}
|
||||
|
||||
pub struct CosmicWorkspaceV2Data {
|
||||
|
|
@ -164,6 +165,100 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::Pin => {
|
||||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(&workspace)
|
||||
{
|
||||
if let Ok(manager) =
|
||||
workspace.data::<WorkspaceData>().unwrap().manager.upgrade()
|
||||
{
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::SetPin {
|
||||
workspace: workspace_handle,
|
||||
pinned: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::Unpin => {
|
||||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(&workspace)
|
||||
{
|
||||
if let Ok(manager) =
|
||||
workspace.data::<WorkspaceData>().unwrap().manager.upgrade()
|
||||
{
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::SetPin {
|
||||
workspace: workspace_handle,
|
||||
pinned: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::MoveBefore {
|
||||
other_workspace,
|
||||
axis,
|
||||
} => {
|
||||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(&workspace)
|
||||
{
|
||||
if let Some(other_workspace) = state
|
||||
.workspace_state()
|
||||
.get_ext_workspace_handle(&other_workspace)
|
||||
{
|
||||
if let Ok(manager) =
|
||||
workspace.data::<WorkspaceData>().unwrap().manager.upgrade()
|
||||
{
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::MoveBefore {
|
||||
workspace: workspace_handle,
|
||||
other_workspace,
|
||||
axis,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::MoveAfter {
|
||||
other_workspace,
|
||||
axis,
|
||||
} => {
|
||||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(&workspace)
|
||||
{
|
||||
if let Some(other_workspace) = state
|
||||
.workspace_state()
|
||||
.get_ext_workspace_handle(&other_workspace)
|
||||
{
|
||||
if let Ok(manager) =
|
||||
workspace.data::<WorkspaceData>().unwrap().manager.upgrade()
|
||||
{
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::MoveAfter {
|
||||
workspace: workspace_handle,
|
||||
other_workspace,
|
||||
axis,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::Destroy => {}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
@ -193,6 +288,12 @@ pub fn send_workspace_to_client(
|
|||
WorkspaceCapabilities::SetTilingState => {
|
||||
Some(zcosmic_workspace_handle_v2::WorkspaceCapabilities::SetTilingState)
|
||||
}
|
||||
WorkspaceCapabilities::Pin => {
|
||||
Some(zcosmic_workspace_handle_v2::WorkspaceCapabilities::Pin)
|
||||
}
|
||||
WorkspaceCapabilities::Move => {
|
||||
Some(zcosmic_workspace_handle_v2::WorkspaceCapabilities::Move)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect::<zcosmic_workspace_handle_v2::WorkspaceCapabilities>();
|
||||
|
|
@ -212,5 +313,21 @@ pub fn send_workspace_to_client(
|
|||
changed = true;
|
||||
}
|
||||
|
||||
if instance.version() >= zcosmic_workspace_handle_v2::EVT_STATE_SINCE {
|
||||
let states = workspace
|
||||
.states
|
||||
.iter()
|
||||
.filter_map(|state| match state {
|
||||
State::Pinned => Some(zcosmic_workspace_handle_v2::State::Pinned),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<zcosmic_workspace_handle_v2::State>();
|
||||
if handle_state.states != Some(states) {
|
||||
instance.state(states);
|
||||
handle_state.states = Some(states);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
changed
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use smithay::{
|
|||
use std::{collections::HashSet, sync::Mutex};
|
||||
|
||||
use super::{
|
||||
Request, Workspace, WorkspaceCapabilities, WorkspaceGlobalData, WorkspaceGroup,
|
||||
Request, State, Workspace, WorkspaceCapabilities, WorkspaceGlobalData, WorkspaceGroup,
|
||||
WorkspaceGroupHandle, WorkspaceHandler, WorkspaceState,
|
||||
};
|
||||
|
||||
|
|
@ -469,12 +469,23 @@ where
|
|||
changed = true;
|
||||
}
|
||||
|
||||
if handle_state.states != Some(workspace.states) {
|
||||
instance.state(workspace.states);
|
||||
handle_state.states = Some(workspace.states.clone());
|
||||
let states = workspace
|
||||
.states
|
||||
.iter()
|
||||
.filter_map(|state| match state {
|
||||
State::Active => Some(ext_workspace_handle_v1::State::Active),
|
||||
State::Urgent => Some(ext_workspace_handle_v1::State::Urgent),
|
||||
State::Hidden => Some(ext_workspace_handle_v1::State::Hidden),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
if handle_state.states != Some(states) {
|
||||
instance.state(states);
|
||||
handle_state.states = Some(states);
|
||||
changed = true;
|
||||
}
|
||||
// TODO ext_workspace_handle_v1::id
|
||||
// TODO send id if pinned
|
||||
|
||||
if let Some(cosmic_v2_handle) = handle_state
|
||||
.cosmic_v2_handle
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use smithay::{
|
|||
reexports::{
|
||||
wayland_protocols::ext::workspace::v1::server::{
|
||||
ext_workspace_group_handle_v1::{ExtWorkspaceGroupHandleV1, GroupCapabilities},
|
||||
ext_workspace_handle_v1::{self, ExtWorkspaceHandleV1},
|
||||
ext_workspace_handle_v1::ExtWorkspaceHandleV1,
|
||||
ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
||||
},
|
||||
wayland_server::{
|
||||
|
|
@ -38,6 +38,19 @@ bitflags::bitflags! {
|
|||
const Rename = 16;
|
||||
/// cosmic specific
|
||||
const SetTilingState = 32;
|
||||
const Pin = 64;
|
||||
const Move = 128;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct State: u32 {
|
||||
const Active = 1;
|
||||
const Urgent = 2;
|
||||
const Hidden = 4;
|
||||
/// cosmic specific
|
||||
const Pinned = 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +109,7 @@ pub struct Workspace {
|
|||
name: String,
|
||||
capabilities: WorkspaceCapabilities,
|
||||
coordinates: Vec<u32>,
|
||||
states: ext_workspace_handle_v1::State,
|
||||
states: State,
|
||||
tiling: zcosmic_workspace_handle_v2::TilingState,
|
||||
ext_id: Option<String>,
|
||||
}
|
||||
|
|
@ -148,6 +161,20 @@ pub enum Request {
|
|||
workspace: WorkspaceHandle,
|
||||
group: WorkspaceGroupHandle,
|
||||
},
|
||||
SetPin {
|
||||
workspace: WorkspaceHandle,
|
||||
pinned: bool,
|
||||
},
|
||||
MoveBefore {
|
||||
workspace: WorkspaceHandle,
|
||||
other_workspace: WorkspaceHandle,
|
||||
axis: u32,
|
||||
},
|
||||
MoveAfter {
|
||||
workspace: WorkspaceHandle,
|
||||
other_workspace: WorkspaceHandle,
|
||||
axis: u32,
|
||||
},
|
||||
}
|
||||
|
||||
impl<D> WorkspaceState<D>
|
||||
|
|
@ -166,7 +193,7 @@ where
|
|||
);
|
||||
|
||||
let cosmic_v2_global = dh.create_global::<D, ZcosmicWorkspaceManagerV2, _>(
|
||||
1,
|
||||
2,
|
||||
WorkspaceGlobalData {
|
||||
filter: Box::new(client_filter.clone()),
|
||||
},
|
||||
|
|
@ -240,10 +267,7 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
pub fn workspace_states(
|
||||
&self,
|
||||
workspace: &WorkspaceHandle,
|
||||
) -> Option<ext_workspace_handle_v1::State> {
|
||||
pub fn workspace_states(&self, workspace: &WorkspaceHandle) -> Option<State> {
|
||||
self.groups
|
||||
.iter()
|
||||
.find_map(|g| Some(g.workspaces.iter().find(|w| w.id == workspace.id)?.states))
|
||||
|
|
@ -332,6 +356,7 @@ where
|
|||
&mut self,
|
||||
group: &WorkspaceGroupHandle,
|
||||
tiling: zcosmic_workspace_handle_v2::TilingState,
|
||||
// TODO way to add id to workspace that doesn't have it
|
||||
ext_id: Option<String>,
|
||||
) -> Option<WorkspaceHandle> {
|
||||
if let Some(group) = self.0.groups.iter_mut().find(|g| g.id == group.id) {
|
||||
|
|
@ -343,7 +368,7 @@ where
|
|||
name: Default::default(),
|
||||
capabilities: WorkspaceCapabilities::empty(),
|
||||
coordinates: Default::default(),
|
||||
states: ext_workspace_handle_v1::State::empty(),
|
||||
states: State::empty(),
|
||||
ext_id,
|
||||
};
|
||||
group.workspaces.push(workspace);
|
||||
|
|
@ -538,18 +563,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn workspace_states(
|
||||
&self,
|
||||
workspace: &WorkspaceHandle,
|
||||
) -> Option<ext_workspace_handle_v1::State> {
|
||||
pub fn workspace_states(&self, workspace: &WorkspaceHandle) -> Option<State> {
|
||||
self.0.workspace_states(workspace)
|
||||
}
|
||||
|
||||
pub fn add_workspace_state(
|
||||
&mut self,
|
||||
workspace: &WorkspaceHandle,
|
||||
state: ext_workspace_handle_v1::State,
|
||||
) {
|
||||
pub fn add_workspace_state(&mut self, workspace: &WorkspaceHandle, state: State) {
|
||||
if let Some(workspace) = self
|
||||
.0
|
||||
.groups
|
||||
|
|
@ -560,11 +578,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_workspace_state(
|
||||
&mut self,
|
||||
workspace: &WorkspaceHandle,
|
||||
state: ext_workspace_handle_v1::State,
|
||||
) {
|
||||
pub fn remove_workspace_state(&mut self, workspace: &WorkspaceHandle, state: State) {
|
||||
if let Some(workspace) = self
|
||||
.0
|
||||
.groups
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue