Add ext-foreign-toplevel-list-v1 protocol
This commit is contained in:
parent
59b0e0e74e
commit
1342c000ab
9 changed files with 96 additions and 4 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -4703,7 +4703,7 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/smithay//smithay?rev=5dc0153#5dc015361c641cd76d4abbd60dd8896dd8cb8adc"
|
source = "git+https://github.com/smithay//smithay?rev=298bef3#298bef358d4bbffd3a1159dc2ec418b9f81417cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"appendlist",
|
"appendlist",
|
||||||
"ash 0.38.0+1.3.281",
|
"ash 0.38.0+1.3.281",
|
||||||
|
|
|
||||||
|
|
@ -116,4 +116,4 @@ inherits = "release"
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
|
|
||||||
[patch."https://github.com/Smithay/smithay.git"]
|
[patch."https://github.com/Smithay/smithay.git"]
|
||||||
smithay = { git = "https://github.com/smithay//smithay", rev = "5dc0153" }
|
smithay = { git = "https://github.com/smithay//smithay", rev = "298bef3" }
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ use smithay::{
|
||||||
utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
|
utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::with_states,
|
||||||
|
foreign_toplevel_list::ForeignToplevelListState,
|
||||||
seat::WaylandFocus,
|
seat::WaylandFocus,
|
||||||
session_lock::LockSurface,
|
session_lock::LockSurface,
|
||||||
shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState},
|
shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState},
|
||||||
|
|
@ -55,7 +56,11 @@ use crate::{
|
||||||
utils::{prelude::*, quirks::WORKSPACE_OVERVIEW_NAMESPACE},
|
utils::{prelude::*, quirks::WORKSPACE_OVERVIEW_NAMESPACE},
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::{
|
handlers::{
|
||||||
toplevel_management::minimize_rectangle, xdg_activation::ActivationContext,
|
foreign_toplevel_list::{
|
||||||
|
new_foreign_toplevel, refresh_foreign_toplevels, remove_foreign_toplevel,
|
||||||
|
},
|
||||||
|
toplevel_management::minimize_rectangle,
|
||||||
|
xdg_activation::ActivationContext,
|
||||||
xdg_shell::popup::get_popup_toplevel,
|
xdg_shell::popup::get_popup_toplevel,
|
||||||
},
|
},
|
||||||
protocols::{
|
protocols::{
|
||||||
|
|
@ -1184,6 +1189,7 @@ impl Common {
|
||||||
);
|
);
|
||||||
self.popups.cleanup();
|
self.popups.cleanup();
|
||||||
self.toplevel_info_state.refresh(&self.workspace_state);
|
self.toplevel_info_state.refresh(&self.workspace_state);
|
||||||
|
refresh_foreign_toplevels(&self.shell.read().unwrap());
|
||||||
self.refresh_idle_inhibit();
|
self.refresh_idle_inhibit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1851,6 +1857,7 @@ impl Shell {
|
||||||
&mut self,
|
&mut self,
|
||||||
window: &CosmicSurface,
|
window: &CosmicSurface,
|
||||||
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
|
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
|
||||||
|
foreign_toplevel_list: &mut ForeignToplevelListState,
|
||||||
workspace_state: &mut WorkspaceState<State>,
|
workspace_state: &mut WorkspaceState<State>,
|
||||||
evlh: &LoopHandle<'static, State>,
|
evlh: &LoopHandle<'static, State>,
|
||||||
) -> Option<KeyboardFocusTarget> {
|
) -> Option<KeyboardFocusTarget> {
|
||||||
|
|
@ -1933,6 +1940,7 @@ impl Shell {
|
||||||
toplevel_info.new_toplevel(&window, workspace_state);
|
toplevel_info.new_toplevel(&window, workspace_state);
|
||||||
toplevel_enter_output(&window, &output);
|
toplevel_enter_output(&window, &output);
|
||||||
toplevel_enter_workspace(&window, &workspace.handle);
|
toplevel_enter_workspace(&window, &workspace.handle);
|
||||||
|
new_foreign_toplevel(&window, foreign_toplevel_list);
|
||||||
|
|
||||||
let mut workspace_state = workspace_state.update();
|
let mut workspace_state = workspace_state.update();
|
||||||
|
|
||||||
|
|
@ -2064,6 +2072,7 @@ impl Shell {
|
||||||
surface: &S,
|
surface: &S,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
|
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
|
||||||
|
foreign_toplevel_list: &mut ForeignToplevelListState,
|
||||||
) where
|
) where
|
||||||
CosmicSurface: PartialEq<S>,
|
CosmicSurface: PartialEq<S>,
|
||||||
{
|
{
|
||||||
|
|
@ -2113,6 +2122,7 @@ impl Shell {
|
||||||
|
|
||||||
if let Some(surface) = surface {
|
if let Some(surface) = surface {
|
||||||
toplevel_info.remove_toplevel(&surface);
|
toplevel_info.remove_toplevel(&surface);
|
||||||
|
remove_foreign_toplevel(&surface, foreign_toplevel_list);
|
||||||
self.pending_windows.push((surface, seat.clone(), None));
|
self.pending_windows.push((surface, seat.clone(), None));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ use smithay::{
|
||||||
alpha_modifier::AlphaModifierState,
|
alpha_modifier::AlphaModifierState,
|
||||||
compositor::{CompositorClientState, CompositorState, SurfaceData},
|
compositor::{CompositorClientState, CompositorState, SurfaceData},
|
||||||
dmabuf::{DmabufFeedback, DmabufGlobal, DmabufState},
|
dmabuf::{DmabufFeedback, DmabufGlobal, DmabufState},
|
||||||
|
foreign_toplevel_list::ForeignToplevelListState,
|
||||||
fractional_scale::{with_fractional_scale, FractionalScaleManagerState},
|
fractional_scale::{with_fractional_scale, FractionalScaleManagerState},
|
||||||
idle_inhibit::IdleInhibitManagerState,
|
idle_inhibit::IdleInhibitManagerState,
|
||||||
idle_notify::IdleNotifierState,
|
idle_notify::IdleNotifierState,
|
||||||
|
|
@ -192,6 +193,7 @@ pub struct Common {
|
||||||
pub compositor_state: CompositorState,
|
pub compositor_state: CompositorState,
|
||||||
pub data_device_state: DataDeviceState,
|
pub data_device_state: DataDeviceState,
|
||||||
pub dmabuf_state: DmabufState,
|
pub dmabuf_state: DmabufState,
|
||||||
|
pub foreign_toplevel_list: ForeignToplevelListState,
|
||||||
pub fractional_scale_state: FractionalScaleManagerState,
|
pub fractional_scale_state: FractionalScaleManagerState,
|
||||||
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
|
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
|
||||||
pub output_state: OutputManagerState,
|
pub output_state: OutputManagerState,
|
||||||
|
|
@ -486,6 +488,8 @@ impl State {
|
||||||
let compositor_state = CompositorState::new::<Self>(dh);
|
let compositor_state = CompositorState::new::<Self>(dh);
|
||||||
let data_device_state = DataDeviceState::new::<Self>(dh);
|
let data_device_state = DataDeviceState::new::<Self>(dh);
|
||||||
let dmabuf_state = DmabufState::new();
|
let dmabuf_state = DmabufState::new();
|
||||||
|
let foreign_toplevel_list =
|
||||||
|
ForeignToplevelListState::new_with_filter::<State>(dh, client_is_privileged);
|
||||||
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
|
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
|
||||||
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
|
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
|
||||||
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
|
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
|
||||||
|
|
@ -581,6 +585,7 @@ impl State {
|
||||||
compositor_state,
|
compositor_state,
|
||||||
data_device_state,
|
data_device_state,
|
||||||
dmabuf_state,
|
dmabuf_state,
|
||||||
|
foreign_toplevel_list,
|
||||||
fractional_scale_state,
|
fractional_scale_state,
|
||||||
idle_notifier_state,
|
idle_notifier_state,
|
||||||
idle_inhibit_manager_state,
|
idle_inhibit_manager_state,
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,7 @@ impl State {
|
||||||
let res = shell.map_window(
|
let res = shell.map_window(
|
||||||
&window,
|
&window,
|
||||||
&mut self.common.toplevel_info_state,
|
&mut self.common.toplevel_info_state,
|
||||||
|
&mut self.common.foreign_toplevel_list,
|
||||||
&mut self.common.workspace_state,
|
&mut self.common.workspace_state,
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
68
src/wayland/handlers/foreign_toplevel_list.rs
Normal file
68
src/wayland/handlers/foreign_toplevel_list.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
shell::{CosmicSurface, Shell},
|
||||||
|
state::State,
|
||||||
|
};
|
||||||
|
use smithay::wayland::foreign_toplevel_list::{
|
||||||
|
ForeignToplevelHandle, ForeignToplevelListHandler, ForeignToplevelListState,
|
||||||
|
};
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
impl ForeignToplevelListHandler for State {
|
||||||
|
fn foreign_toplevel_list_state(&mut self) -> &mut ForeignToplevelListState {
|
||||||
|
&mut self.common.foreign_toplevel_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_foreign_toplevel(
|
||||||
|
window: &CosmicSurface,
|
||||||
|
foreign_toplevel_list: &mut ForeignToplevelListState,
|
||||||
|
) {
|
||||||
|
let toplevel_handle =
|
||||||
|
foreign_toplevel_list.new_toplevel::<State>(window.title(), window.app_id());
|
||||||
|
*window
|
||||||
|
.user_data()
|
||||||
|
.get_or_insert::<Mutex<Option<ForeignToplevelHandle>>, _>(Default::default)
|
||||||
|
.lock()
|
||||||
|
.unwrap() = Some(toplevel_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_foreign_toplevel(
|
||||||
|
window: &CosmicSurface,
|
||||||
|
foreign_toplevel_list: &mut ForeignToplevelListState,
|
||||||
|
) {
|
||||||
|
if let Some(handle) = window
|
||||||
|
.user_data()
|
||||||
|
.get::<Mutex<Option<ForeignToplevelHandle>>>()
|
||||||
|
{
|
||||||
|
if let Some(handle) = handle.lock().unwrap().take() {
|
||||||
|
foreign_toplevel_list.remove_toplevel(&handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh_foreign_toplevels(shell: &Shell) {
|
||||||
|
for (window, _) in shell
|
||||||
|
.workspaces
|
||||||
|
.spaces()
|
||||||
|
.flat_map(|workspace| workspace.mapped())
|
||||||
|
.flat_map(|mapped| mapped.windows())
|
||||||
|
{
|
||||||
|
let foreign_toplevel_handle = window
|
||||||
|
.user_data()
|
||||||
|
.get::<Mutex<Option<ForeignToplevelHandle>>>()
|
||||||
|
.and_then(|handle| handle.lock().unwrap().clone());
|
||||||
|
if let Some(handle) = foreign_toplevel_handle {
|
||||||
|
let app_id = window.app_id();
|
||||||
|
let title = window.title();
|
||||||
|
if handle.app_id() != app_id || handle.title() != title {
|
||||||
|
handle.send_app_id(&app_id);
|
||||||
|
handle.send_title(&title);
|
||||||
|
handle.send_done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
smithay::delegate_foreign_toplevel_list!(State);
|
||||||
|
|
@ -9,6 +9,7 @@ pub mod decoration;
|
||||||
pub mod dmabuf;
|
pub mod dmabuf;
|
||||||
pub mod drm;
|
pub mod drm;
|
||||||
pub mod drm_lease;
|
pub mod drm_lease;
|
||||||
|
pub mod foreign_toplevel_list;
|
||||||
pub mod fractional_scale;
|
pub mod fractional_scale;
|
||||||
pub mod idle_inhibit;
|
pub mod idle_inhibit;
|
||||||
pub mod idle_notify;
|
pub mod idle_notify;
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,7 @@ impl XdgShellHandler for State {
|
||||||
surface.wl_surface(),
|
surface.wl_surface(),
|
||||||
&seat,
|
&seat,
|
||||||
&mut self.common.toplevel_info_state,
|
&mut self.common.toplevel_info_state,
|
||||||
|
&mut self.common.foreign_toplevel_list,
|
||||||
);
|
);
|
||||||
|
|
||||||
let output = shell
|
let output = shell
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,7 @@ impl XwmHandler for State {
|
||||||
let res = shell.map_window(
|
let res = shell.map_window(
|
||||||
&window,
|
&window,
|
||||||
&mut self.common.toplevel_info_state,
|
&mut self.common.toplevel_info_state,
|
||||||
|
&mut self.common.foreign_toplevel_list,
|
||||||
&mut self.common.workspace_state,
|
&mut self.common.workspace_state,
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
@ -342,7 +343,12 @@ impl XwmHandler for State {
|
||||||
shell.override_redirect_windows.retain(|or| or != &window);
|
shell.override_redirect_windows.retain(|or| or != &window);
|
||||||
} else {
|
} else {
|
||||||
let seat = shell.seats.last_active().clone();
|
let seat = shell.seats.last_active().clone();
|
||||||
shell.unmap_surface(&window, &seat, &mut self.common.toplevel_info_state);
|
shell.unmap_surface(
|
||||||
|
&window,
|
||||||
|
&seat,
|
||||||
|
&mut self.common.toplevel_info_state,
|
||||||
|
&mut self.common.foreign_toplevel_list,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let outputs = if let Some(wl_surface) = window.wl_surface() {
|
let outputs = if let Some(wl_surface) = window.wl_surface() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue