workspace-management: Implement move_to_workspace request
Needed for `cosmic-workspaces`.
This commit is contained in:
parent
75990ff056
commit
656996503c
6 changed files with 92 additions and 43 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -641,7 +641,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-protocols"
|
name = "cosmic-protocols"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#5faec87be0a1fd1d72e99431ac8e6647ff1dfd41"
|
source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#c1b651630c2b71cd8dfd2eb4ab47ede9dbd63840"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
|
|
@ -954,7 +954,7 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libloading 0.8.1",
|
"libloading 0.7.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ fn move_prev_workspace(state: &mut State, mapped: &CosmicMapped) {
|
||||||
if let Some(prev_handle) = maybe_handle {
|
if let Some(prev_handle) = maybe_handle {
|
||||||
Shell::move_window(
|
Shell::move_window(
|
||||||
state,
|
state,
|
||||||
&seat,
|
Some(&seat),
|
||||||
mapped,
|
mapped,
|
||||||
¤t_handle,
|
¤t_handle,
|
||||||
&prev_handle,
|
&prev_handle,
|
||||||
|
|
@ -93,7 +93,7 @@ fn move_next_workspace(state: &mut State, mapped: &CosmicMapped) {
|
||||||
if let Some(next_handle) = maybe_handle {
|
if let Some(next_handle) = maybe_handle {
|
||||||
Shell::move_window(
|
Shell::move_window(
|
||||||
state,
|
state,
|
||||||
&seat,
|
Some(&seat),
|
||||||
mapped,
|
mapped,
|
||||||
¤t_handle,
|
¤t_handle,
|
||||||
&next_handle,
|
&next_handle,
|
||||||
|
|
|
||||||
|
|
@ -1710,7 +1710,7 @@ impl Shell {
|
||||||
|
|
||||||
pub fn move_window(
|
pub fn move_window(
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
seat: &Seat<State>,
|
seat: Option<&Seat<State>>,
|
||||||
mapped: &CosmicMapped,
|
mapped: &CosmicMapped,
|
||||||
from: &WorkspaceHandle,
|
from: &WorkspaceHandle,
|
||||||
to: &WorkspaceHandle,
|
to: &WorkspaceHandle,
|
||||||
|
|
@ -1759,7 +1759,9 @@ impl Shell {
|
||||||
state.common.shell.update_reactive_popups(&mapped);
|
state.common.shell.update_reactive_popups(&mapped);
|
||||||
}
|
}
|
||||||
let new_pos = if follow {
|
let new_pos = if follow {
|
||||||
seat.set_active_output(&to_output);
|
if let Some(seat) = seat {
|
||||||
|
seat.set_active_output(&to_output);
|
||||||
|
}
|
||||||
state
|
state
|
||||||
.common
|
.common
|
||||||
.shell
|
.shell
|
||||||
|
|
@ -1776,13 +1778,13 @@ impl Shell {
|
||||||
.workspaces
|
.workspaces
|
||||||
.space_for_handle_mut(to)
|
.space_for_handle_mut(to)
|
||||||
.unwrap(); // checked above
|
.unwrap(); // checked above
|
||||||
let focus_stack = to_workspace.focus_stack.get(&seat);
|
let focus_stack = seat.map(|seat| to_workspace.focus_stack.get(&seat));
|
||||||
if window_state.layer == ManagedLayer::Floating {
|
if window_state.layer == ManagedLayer::Floating {
|
||||||
to_workspace.floating_layer.map(mapped.clone(), None);
|
to_workspace.floating_layer.map(mapped.clone(), None);
|
||||||
} else {
|
} else {
|
||||||
to_workspace.tiling_layer.map(
|
to_workspace.tiling_layer.map(
|
||||||
mapped.clone(),
|
mapped.clone(),
|
||||||
Some(focus_stack.iter()),
|
focus_stack.as_ref().map(|x| x.iter()),
|
||||||
direction,
|
direction,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
@ -1852,7 +1854,9 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
if follow {
|
if follow {
|
||||||
Common::set_focus(state, Some(&focus_target), &seat, None);
|
if let Some(seat) = seat {
|
||||||
|
Common::set_focus(state, Some(&focus_target), &seat, None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_pos
|
new_pos
|
||||||
|
|
@ -1893,7 +1897,13 @@ impl Shell {
|
||||||
let from = from_workspace.handle;
|
let from = from_workspace.handle;
|
||||||
|
|
||||||
Ok(Shell::move_window(
|
Ok(Shell::move_window(
|
||||||
state, seat, &mapped, &from, &to, follow, direction,
|
state,
|
||||||
|
Some(seat),
|
||||||
|
&mapped,
|
||||||
|
&from,
|
||||||
|
&to,
|
||||||
|
follow,
|
||||||
|
direction,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use smithay::{input::Seat, reexports::wayland_server::DisplayHandle};
|
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1;
|
||||||
|
use smithay::{input::Seat, output::Output, reexports::wayland_server::DisplayHandle};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::CosmicSurface,
|
shell::{CosmicSurface, Shell},
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::protocols::{
|
wayland::protocols::{
|
||||||
toplevel_info::ToplevelInfoHandler,
|
toplevel_info::ToplevelInfoHandler,
|
||||||
|
|
@ -59,6 +60,35 @@ impl ToplevelManagementHandler for State {
|
||||||
fn close(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
|
fn close(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn move_to_workspace(
|
||||||
|
&mut self,
|
||||||
|
_dh: &DisplayHandle,
|
||||||
|
window: &<Self as ToplevelInfoHandler>::Window,
|
||||||
|
workspace: ZcosmicWorkspaceHandleV1,
|
||||||
|
_output: Output,
|
||||||
|
) {
|
||||||
|
let Some(to_handle) = self.common.shell.workspace_state.get_workspace_handle(&workspace) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_workspace = self
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.workspaces
|
||||||
|
.spaces()
|
||||||
|
.find(|w| w.windows().any(|w| &w == window));
|
||||||
|
if let Some(from_workspace) = from_workspace {
|
||||||
|
let mapped = from_workspace
|
||||||
|
.mapped()
|
||||||
|
.find(|m| m.windows().any(|(w, _)| &w == window))
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let from_handle = from_workspace.handle;
|
||||||
|
let _ = Shell::move_window(self, None, &mapped, &from_handle, &to_handle, false, None);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ManagementWindow for CosmicSurface {
|
impl ManagementWindow for CosmicSurface {
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,11 @@ use smithay::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplelevelManagementCapabilitiesV1 as ManagementCapabilities;
|
pub use cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplelevelManagementCapabilitiesV1 as ManagementCapabilities;
|
||||||
use cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::{
|
use cosmic_protocols::{
|
||||||
self, ZcosmicToplevelManagerV1,
|
toplevel_management::v1::server::zcosmic_toplevel_manager_v1::{
|
||||||
|
self, ZcosmicToplevelManagerV1,
|
||||||
|
},
|
||||||
|
workspace::v1::server::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::toplevel_info::{window_from_handle, ToplevelInfoHandler, ToplevelState, Window};
|
use super::toplevel_info::{window_from_handle, ToplevelInfoHandler, ToplevelState, Window};
|
||||||
|
|
@ -58,6 +61,14 @@ where
|
||||||
fn unmaximize(&mut self, dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {}
|
fn unmaximize(&mut self, dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {}
|
||||||
fn minimize(&mut self, dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {}
|
fn minimize(&mut self, dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {}
|
||||||
fn unminimize(&mut self, dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {}
|
fn unminimize(&mut self, dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {}
|
||||||
|
fn move_to_workspace(
|
||||||
|
&mut self,
|
||||||
|
dh: &DisplayHandle,
|
||||||
|
window: &<Self as ToplevelInfoHandler>::Window,
|
||||||
|
workspace: ZcosmicWorkspaceHandleV1,
|
||||||
|
output: Output,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ToplevelManagerGlobalData {
|
pub struct ToplevelManagerGlobalData {
|
||||||
|
|
@ -79,7 +90,7 @@ impl ToplevelManagementState {
|
||||||
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static,
|
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let global = dh.create_global::<D, ZcosmicToplevelManagerV1, _>(
|
let global = dh.create_global::<D, ZcosmicToplevelManagerV1, _>(
|
||||||
1,
|
2,
|
||||||
ToplevelManagerGlobalData {
|
ToplevelManagerGlobalData {
|
||||||
filter: Box::new(client_filter),
|
filter: Box::new(client_filter),
|
||||||
},
|
},
|
||||||
|
|
@ -221,6 +232,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zcosmic_toplevel_manager_v1::Request::MoveToWorkspace {
|
||||||
|
toplevel,
|
||||||
|
workspace,
|
||||||
|
output,
|
||||||
|
} => {
|
||||||
|
let window = window_from_handle(toplevel).unwrap();
|
||||||
|
if let Some(output) = Output::from_resource(&output) {
|
||||||
|
state.move_to_workspace(dh, &window, workspace, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -307,58 +307,36 @@ where
|
||||||
) {
|
) {
|
||||||
match request {
|
match request {
|
||||||
zcosmic_workspace_handle_v1::Request::Activate => {
|
zcosmic_workspace_handle_v1::Request::Activate => {
|
||||||
if let Some(id) = state
|
if let Some(workspace_handle) = state.workspace_state().get_workspace_handle(obj) {
|
||||||
.workspace_state()
|
|
||||||
.groups
|
|
||||||
.iter()
|
|
||||||
.find_map(|g| g.workspaces.iter().find(|w| w.instances.contains(obj)))
|
|
||||||
.map(|w| w.id)
|
|
||||||
{
|
|
||||||
let mut state = client
|
let mut state = client
|
||||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.workspace_state()
|
.workspace_state()
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
state
|
state.requests.push(Request::Activate(workspace_handle));
|
||||||
.requests
|
|
||||||
.push(Request::Activate(WorkspaceHandle { id }));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zcosmic_workspace_handle_v1::Request::Deactivate => {
|
zcosmic_workspace_handle_v1::Request::Deactivate => {
|
||||||
if let Some(id) = state
|
if let Some(workspace_handle) = state.workspace_state().get_workspace_handle(obj) {
|
||||||
.workspace_state()
|
|
||||||
.groups
|
|
||||||
.iter()
|
|
||||||
.find_map(|g| g.workspaces.iter().find(|w| w.instances.contains(obj)))
|
|
||||||
.map(|w| w.id)
|
|
||||||
{
|
|
||||||
let mut state = client
|
let mut state = client
|
||||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.workspace_state()
|
.workspace_state()
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
state
|
state.requests.push(Request::Deactivate(workspace_handle));
|
||||||
.requests
|
|
||||||
.push(Request::Deactivate(WorkspaceHandle { id }));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zcosmic_workspace_handle_v1::Request::Remove => {
|
zcosmic_workspace_handle_v1::Request::Remove => {
|
||||||
if let Some(id) = state
|
if let Some(workspace_handle) = state.workspace_state().get_workspace_handle(obj) {
|
||||||
.workspace_state()
|
|
||||||
.groups
|
|
||||||
.iter()
|
|
||||||
.find_map(|g| g.workspaces.iter().find(|w| w.instances.contains(obj)))
|
|
||||||
.map(|w| w.id)
|
|
||||||
{
|
|
||||||
let mut state = client
|
let mut state = client
|
||||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.workspace_state()
|
.workspace_state()
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
state.requests.push(Request::Remove(WorkspaceHandle { id }));
|
state.requests.push(Request::Remove(workspace_handle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zcosmic_workspace_handle_v1::Request::Destroy => {
|
zcosmic_workspace_handle_v1::Request::Destroy => {
|
||||||
|
|
@ -556,6 +534,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_workspace_handle(
|
||||||
|
&self,
|
||||||
|
handle: &ZcosmicWorkspaceHandleV1,
|
||||||
|
) -> Option<WorkspaceHandle> {
|
||||||
|
self.groups
|
||||||
|
.iter()
|
||||||
|
.find_map(|g| g.workspaces.iter().find(|w| w.instances.contains(handle)))
|
||||||
|
.map(|w| WorkspaceHandle { id: w.id })
|
||||||
|
}
|
||||||
|
|
||||||
pub fn global_id(&self) -> GlobalId {
|
pub fn global_id(&self) -> GlobalId {
|
||||||
self.global.clone()
|
self.global.clone()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue