state: Move shell behind RwLock
This commit is contained in:
parent
647deb81f1
commit
5d5a510691
45 changed files with 2657 additions and 2097 deletions
|
|
@ -26,66 +26,57 @@ use smithay::{
|
|||
};
|
||||
use std::sync::Mutex;
|
||||
|
||||
impl State {
|
||||
fn toplevel_ensure_initial_configure(&mut self, toplevel: &ToplevelSurface) -> bool {
|
||||
// send the initial configure if relevant
|
||||
let initial_configure_sent = with_states(toplevel.wl_surface(), |states| {
|
||||
fn toplevel_ensure_initial_configure(toplevel: &ToplevelSurface) -> bool {
|
||||
// send the initial configure if relevant
|
||||
let initial_configure_sent = with_states(toplevel.wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.initial_configure_sent
|
||||
});
|
||||
if !initial_configure_sent {
|
||||
// TODO: query expected size from shell (without inserting and mapping)
|
||||
toplevel.with_pending_state(|states| states.size = None);
|
||||
toplevel.send_configure();
|
||||
}
|
||||
initial_configure_sent
|
||||
}
|
||||
|
||||
fn xdg_popup_ensure_initial_configure(popup: &PopupKind) {
|
||||
if let PopupKind::Xdg(ref popup) = popup {
|
||||
let initial_configure_sent = with_states(popup.wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
|
||||
.get::<Mutex<XdgPopupSurfaceRoleAttributes>>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.initial_configure_sent
|
||||
});
|
||||
if !initial_configure_sent {
|
||||
// TODO: query expected size from shell (without inserting and mapping)
|
||||
toplevel.with_pending_state(|states| states.size = None);
|
||||
toplevel.send_configure();
|
||||
// NOTE: This should never fail as the initial configure is always
|
||||
// allowed.
|
||||
popup.send_configure().expect("initial configure failed");
|
||||
}
|
||||
initial_configure_sent
|
||||
}
|
||||
}
|
||||
|
||||
fn xdg_popup_ensure_initial_configure(&mut self, popup: &PopupKind) {
|
||||
if let PopupKind::Xdg(ref popup) = popup {
|
||||
let initial_configure_sent = with_states(popup.wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<Mutex<XdgPopupSurfaceRoleAttributes>>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.initial_configure_sent
|
||||
});
|
||||
if !initial_configure_sent {
|
||||
// NOTE: This should never fail as the initial configure is always
|
||||
// allowed.
|
||||
popup.send_configure().expect("initial configure failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
fn layer_surface_check_inital_configure(surface: &LayerSurface) -> bool {
|
||||
// send the initial configure if relevant
|
||||
let initial_configure_sent = with_states(surface.wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<Mutex<LayerSurfaceAttributes>>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.initial_configure_sent
|
||||
});
|
||||
|
||||
fn layer_surface_ensure_inital_configure(&mut self, surface: &LayerSurface) -> bool {
|
||||
// send the initial configure if relevant
|
||||
let initial_configure_sent = with_states(surface.wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<Mutex<LayerSurfaceAttributes>>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.initial_configure_sent
|
||||
});
|
||||
if !initial_configure_sent {
|
||||
// compute initial dimensions by mapping
|
||||
if let Some(target) = self.common.shell.map_layer(&surface) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
Shell::set_focus(self, Some(&target), &seat, None);
|
||||
}
|
||||
surface.layer_surface().send_configure();
|
||||
}
|
||||
initial_configure_sent
|
||||
}
|
||||
initial_configure_sent
|
||||
}
|
||||
|
||||
pub fn client_compositor_state<'a>(client: &'a Client) -> &'a CompositorClientState {
|
||||
|
|
@ -147,48 +138,67 @@ impl CompositorHandler for State {
|
|||
// first load the buffer for various smithay helper functions (which also initializes the RendererSurfaceState)
|
||||
on_commit_buffer_handler::<Self>(surface);
|
||||
|
||||
// and refresh smithays internal state
|
||||
self.common.on_commit(surface);
|
||||
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
|
||||
// schedule a new render
|
||||
if let Some(output) = shell.visible_output_for_surface(surface) {
|
||||
self.backend
|
||||
.schedule_render(&self.common.event_loop_handle, &output);
|
||||
}
|
||||
|
||||
// handle initial configure events and map windows if necessary
|
||||
if let Some((window, _, _)) = self
|
||||
.common
|
||||
.shell
|
||||
if let Some((window, _, _)) = shell
|
||||
.pending_windows
|
||||
.iter()
|
||||
.find(|(window, _, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
.cloned()
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
if self.toplevel_ensure_initial_configure(&toplevel)
|
||||
if toplevel_ensure_initial_configure(&toplevel)
|
||||
&& with_renderer_surface_state(&surface, |state| state.buffer().is_some())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
window.on_commit();
|
||||
if let Some(target) = self.common.shell.map_window(
|
||||
let res = shell.map_window(
|
||||
&window,
|
||||
&mut self.common.toplevel_info_state,
|
||||
&mut self.common.workspace_state,
|
||||
&self.common.event_loop_handle,
|
||||
&self.common.theme,
|
||||
) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
);
|
||||
if let Some(target) = res {
|
||||
let seat = shell.seats.last_active().clone();
|
||||
std::mem::drop(shell);
|
||||
Shell::set_focus(self, Some(&target), &seat, None);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((layer_surface, _, _)) = self
|
||||
.common
|
||||
.shell
|
||||
if let Some((layer_surface, _, _)) = shell
|
||||
.pending_layers
|
||||
.iter()
|
||||
.find(|(layer_surface, _, _)| layer_surface.wl_surface() == surface)
|
||||
.cloned()
|
||||
{
|
||||
if !self.layer_surface_ensure_inital_configure(&layer_surface) {
|
||||
if !layer_surface_check_inital_configure(&layer_surface) {
|
||||
// compute initial dimensions by mapping
|
||||
if let Some(target) = shell.map_layer(&layer_surface) {
|
||||
let seat = shell.seats.last_active().clone();
|
||||
std::mem::drop(shell);
|
||||
Shell::set_focus(self, Some(&target), &seat, None);
|
||||
}
|
||||
layer_surface.layer_surface().send_configure();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(popup) = self.common.shell.popups.find_popup(surface) {
|
||||
self.xdg_popup_ensure_initial_configure(&popup);
|
||||
if let Some(popup) = self.common.popups.find_popup(surface) {
|
||||
xdg_popup_ensure_initial_configure(&popup);
|
||||
return;
|
||||
}
|
||||
|
||||
if with_renderer_surface_state(surface, |state| state.buffer().is_none()).unwrap_or(false) {
|
||||
|
|
@ -197,7 +207,7 @@ impl CompositorHandler for State {
|
|||
// session-lock disallows null commits
|
||||
|
||||
// if it was a move-grab?
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let moved_window = seat
|
||||
.user_data()
|
||||
.get::<SeatMoveGrabState>()
|
||||
|
|
@ -228,9 +238,11 @@ impl CompositorHandler for State {
|
|||
stack.remove_idx(i);
|
||||
}
|
||||
} else {
|
||||
std::mem::drop(shell);
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.unset_grab(self, SERIAL_COUNTER.next_serial(), 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -247,21 +259,16 @@ impl CompositorHandler for State {
|
|||
// If we would re-position the window inside the grab we would get a weird jittery animation.
|
||||
// We only want to resize once the client has acknoledged & commited the new size,
|
||||
// so we need to carefully track the state through different handlers.
|
||||
if let Some(element) = self.common.shell.element_for_surface(surface).cloned() {
|
||||
if let Some(element) = shell.element_for_surface(surface).cloned() {
|
||||
crate::shell::layout::floating::ResizeSurfaceGrab::apply_resize_to_location(
|
||||
element.clone(),
|
||||
&mut self.common.shell,
|
||||
&mut *shell,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// and refresh smithays internal state
|
||||
self.common.shell.on_commit(surface);
|
||||
|
||||
// re-arrange layer-surfaces (commits may change size and positioning)
|
||||
let layer_output = self
|
||||
.common
|
||||
.shell
|
||||
let layer_output = shell
|
||||
.outputs()
|
||||
.find(|o| {
|
||||
let map = layer_map_for_output(o);
|
||||
|
|
@ -269,18 +276,13 @@ impl CompositorHandler for State {
|
|||
.is_some()
|
||||
})
|
||||
.cloned();
|
||||
|
||||
if let Some(output) = layer_output {
|
||||
let changed = layer_map_for_output(&output).arrange();
|
||||
if changed {
|
||||
self.common.shell.workspaces.recalculate();
|
||||
shell.workspaces.recalculate();
|
||||
}
|
||||
}
|
||||
|
||||
// schedule a new render
|
||||
if let Some(output) = self.common.shell.visible_output_for_surface(surface) {
|
||||
self.backend
|
||||
.schedule_render(&self.common.event_loop_handle, &output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,86 +54,85 @@ impl PreferredDecorationMode {
|
|||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode {
|
||||
if mapped.is_stack() {
|
||||
if let Some((window, _)) = mapped
|
||||
.windows()
|
||||
.find(|(window, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(XdgMode::ServerSide)
|
||||
});
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
KdeMode::Server
|
||||
} else {
|
||||
if let Some((window, _)) = mapped
|
||||
.windows()
|
||||
.find(|(window, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(XdgMode::ClientSide)
|
||||
});
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
KdeMode::Client
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_mode(mapped: &CosmicMapped, surface: &WlSurface, mode: XdgMode) {
|
||||
pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode {
|
||||
if mapped.is_stack() {
|
||||
if let Some((window, _)) = mapped
|
||||
.windows()
|
||||
.find(|(window, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
PreferredDecorationMode::update(&window.0, Some(mode));
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(mode);
|
||||
});
|
||||
toplevel
|
||||
.with_pending_state(|state| state.decoration_mode = Some(XdgMode::ServerSide));
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset_mode(mapped: &CosmicMapped, surface: &WlSurface) {
|
||||
KdeMode::Server
|
||||
} else {
|
||||
if let Some((window, _)) = mapped
|
||||
.windows()
|
||||
.find(|(window, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
PreferredDecorationMode::update(&window.0, None);
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = None;
|
||||
});
|
||||
toplevel
|
||||
.with_pending_state(|state| state.decoration_mode = Some(XdgMode::ClientSide));
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
KdeMode::Client
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_mode(mapped: &CosmicMapped, surface: &WlSurface, mode: XdgMode) {
|
||||
if let Some((window, _)) = mapped
|
||||
.windows()
|
||||
.find(|(window, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
PreferredDecorationMode::update(&window.0, Some(mode));
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = Some(mode);
|
||||
});
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset_mode(mapped: &CosmicMapped, surface: &WlSurface) {
|
||||
if let Some((window, _)) = mapped
|
||||
.windows()
|
||||
.find(|(window, _)| window.wl_surface().as_ref() == Some(surface))
|
||||
{
|
||||
if let Some(toplevel) = window.0.toplevel() {
|
||||
PreferredDecorationMode::update(&window.0, None);
|
||||
toplevel.with_pending_state(|state| {
|
||||
state.decoration_mode = None;
|
||||
});
|
||||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl XdgDecorationHandler for State {
|
||||
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
|
||||
State::new_decoration(mapped, toplevel.wl_surface());
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
||||
new_decoration(mapped, toplevel.wl_surface());
|
||||
}
|
||||
}
|
||||
|
||||
fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
|
||||
State::request_mode(mapped, toplevel.wl_surface(), mode);
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
||||
request_mode(mapped, toplevel.wl_surface(), mode);
|
||||
} else {
|
||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
||||
}
|
||||
}
|
||||
|
||||
fn unset_mode(&mut self, toplevel: ToplevelSurface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
|
||||
State::unset_mode(mapped, toplevel.wl_surface())
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
|
||||
unset_mode(mapped, toplevel.wl_surface())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -144,8 +143,9 @@ impl KdeDecorationHandler for State {
|
|||
}
|
||||
|
||||
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(surface) {
|
||||
let mode = State::new_decoration(mapped, surface);
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
||||
let mode = new_decoration(mapped, surface);
|
||||
decoration.mode(mode);
|
||||
}
|
||||
}
|
||||
|
|
@ -157,9 +157,10 @@ impl KdeDecorationHandler for State {
|
|||
mode: WEnum<KdeMode>,
|
||||
) {
|
||||
if let WEnum::Value(mode) = mode {
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
// TODO: We need to store this value until it gets mapped and apply it then, if it is not mapped yet.
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(surface) {
|
||||
State::request_mode(
|
||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
||||
request_mode(
|
||||
mapped,
|
||||
surface,
|
||||
match mode {
|
||||
|
|
@ -173,8 +174,9 @@ impl KdeDecorationHandler for State {
|
|||
}
|
||||
|
||||
fn release(&mut self, _decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(surface) {
|
||||
State::unset_mode(mapped, surface)
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(surface) {
|
||||
unset_mode(mapped, surface)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,11 +41,21 @@ impl FractionalScaleHandler for State {
|
|||
.or_else(|| {
|
||||
self.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.visible_output_for_surface(&surface)
|
||||
.cloned()
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| self.common.shell.seats.last_active().active_output());
|
||||
.unwrap_or_else(|| {
|
||||
self.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.seats
|
||||
.last_active()
|
||||
.active_output()
|
||||
});
|
||||
|
||||
with_states(&surface, |states| {
|
||||
with_fractional_scale(states, |fractional_scale| {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,7 @@ use tracing::warn;
|
|||
|
||||
impl InputMethodHandler for State {
|
||||
fn new_popup(&mut self, surface: PopupSurface) {
|
||||
if let Err(err) = self
|
||||
.common
|
||||
.shell
|
||||
.popups
|
||||
.track_popup(PopupKind::from(surface))
|
||||
{
|
||||
if let Err(err) = self.common.popups.track_popup(PopupKind::from(surface)) {
|
||||
warn!("Failed to track popup: {}", err);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,6 +26,8 @@ impl InputMethodHandler for State {
|
|||
fn parent_geometry(&self, parent: &WlSurface) -> Rectangle<i32, smithay::utils::Logical> {
|
||||
self.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.element_for_surface(parent)
|
||||
.map(|e| e.geometry())
|
||||
.unwrap_or_default()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use smithay::{
|
|||
|
||||
impl WlrLayerShellHandler for State {
|
||||
fn shell_state(&mut self) -> &mut WlrLayerShellState {
|
||||
&mut self.common.shell.layer_shell_state
|
||||
&mut self.common.layer_shell_state
|
||||
}
|
||||
|
||||
fn new_layer_surface(
|
||||
|
|
@ -26,24 +26,22 @@ impl WlrLayerShellHandler for State {
|
|||
_layer: Layer,
|
||||
namespace: String,
|
||||
) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let output = wl_output
|
||||
.as_ref()
|
||||
.and_then(Output::from_resource)
|
||||
.unwrap_or_else(|| seat.active_output());
|
||||
self.common.shell.pending_layers.push((
|
||||
LayerSurface::new(surface, namespace),
|
||||
output,
|
||||
seat,
|
||||
));
|
||||
shell
|
||||
.pending_layers
|
||||
.push((LayerSurface::new(surface, namespace), output, seat));
|
||||
}
|
||||
|
||||
fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
|
||||
self.common.shell.unconstrain_popup(&popup);
|
||||
self.common.shell.read().unwrap().unconstrain_popup(&popup);
|
||||
|
||||
if popup.send_configure().is_ok() {
|
||||
self.common
|
||||
.shell
|
||||
.popups
|
||||
.track_popup(PopupKind::from(popup))
|
||||
.unwrap();
|
||||
|
|
@ -51,9 +49,8 @@ impl WlrLayerShellHandler for State {
|
|||
}
|
||||
|
||||
fn layer_destroyed(&mut self, surface: WlrLayerSurface) {
|
||||
let maybe_output = self
|
||||
.common
|
||||
.shell
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let maybe_output = shell
|
||||
.outputs()
|
||||
.find(|o| {
|
||||
let map = layer_map_for_output(o);
|
||||
|
|
@ -72,7 +69,7 @@ impl WlrLayerShellHandler for State {
|
|||
map.unmap_layer(&layer);
|
||||
}
|
||||
|
||||
self.common.shell.workspaces.recalculate();
|
||||
shell.workspaces.recalculate();
|
||||
|
||||
self.backend
|
||||
.schedule_render(&self.common.event_loop_handle, &output);
|
||||
|
|
|
|||
|
|
@ -82,12 +82,16 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
if let Err(err) = self.backend.apply_config_for_output(
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let res = self.backend.apply_config_for_output(
|
||||
output,
|
||||
test_only,
|
||||
&mut self.common.shell,
|
||||
&mut *shell,
|
||||
&self.common.event_loop_handle,
|
||||
) {
|
||||
&mut self.common.workspace_state.update(),
|
||||
&self.common.xdg_activation_state,
|
||||
);
|
||||
if let Err(err) = res {
|
||||
warn!(
|
||||
?err,
|
||||
"Failed to apply config to {}. Resetting",
|
||||
|
|
@ -106,8 +110,10 @@ impl State {
|
|||
if let Err(err) = self.backend.apply_config_for_output(
|
||||
output,
|
||||
false,
|
||||
&mut self.common.shell,
|
||||
&mut *shell,
|
||||
&self.common.event_loop_handle,
|
||||
&mut self.common.workspace_state.update(),
|
||||
&self.common.xdg_activation_state,
|
||||
) {
|
||||
error!(?err, "Failed to reset output config for {}.", output.name(),);
|
||||
}
|
||||
|
|
@ -115,6 +121,9 @@ impl State {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::mem::drop(shell);
|
||||
self.common.refresh();
|
||||
}
|
||||
|
||||
for output in conf
|
||||
|
|
|
|||
|
|
@ -52,8 +52,9 @@ impl ScreencopyHandler for State {
|
|||
.upgrade()
|
||||
.and_then(|output| constraints_for_output(&output, &mut self.backend)),
|
||||
ImageSourceData::Workspace(handle) => {
|
||||
let workspace = self.common.shell.workspaces.space_for_handle(&handle)?;
|
||||
constraints_for_output(workspace.output(), &mut self.backend)
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
let output = shell.workspaces.space_for_handle(&handle)?.output();
|
||||
constraints_for_output(output, &mut self.backend)
|
||||
}
|
||||
ImageSourceData::Toplevel(window) => {
|
||||
constraints_for_toplevel(window, &mut self.backend)
|
||||
|
|
@ -65,6 +66,8 @@ impl ScreencopyHandler for State {
|
|||
let size = if let Some((geometry, _)) = self
|
||||
.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.seats
|
||||
.last_active()
|
||||
.cursor_geometry((0.0, 0.0), self.common.clock.now())
|
||||
|
|
@ -98,8 +101,8 @@ impl ScreencopyHandler for State {
|
|||
output.add_session(session);
|
||||
}
|
||||
ImageSourceData::Workspace(handle) => {
|
||||
let Some(workspace) = self.common.shell.workspaces.space_for_handle_mut(&handle)
|
||||
else {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else {
|
||||
session.stop();
|
||||
return;
|
||||
};
|
||||
|
|
@ -127,7 +130,14 @@ impl ScreencopyHandler for State {
|
|||
}
|
||||
fn new_cursor_session(&mut self, session: CursorSession) {
|
||||
let (pointer_loc, pointer_size, hotspot) = {
|
||||
let seat = self.common.shell.seats.last_active();
|
||||
let seat = self
|
||||
.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.seats
|
||||
.last_active()
|
||||
.clone();
|
||||
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
let pointer_loc = pointer.current_location().to_i32_round().as_global();
|
||||
|
|
@ -183,8 +193,8 @@ impl ScreencopyHandler for State {
|
|||
output.add_cursor_session(session);
|
||||
}
|
||||
ImageSourceData::Workspace(handle) => {
|
||||
let Some(workspace) = self.common.shell.workspaces.space_for_handle_mut(&handle)
|
||||
else {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else {
|
||||
session.stop();
|
||||
return;
|
||||
};
|
||||
|
|
@ -215,9 +225,10 @@ impl ScreencopyHandler for State {
|
|||
workspace.add_cursor_session(session);
|
||||
}
|
||||
ImageSourceData::Toplevel(mut toplevel) => {
|
||||
if let Some(element) = self.common.shell.element_for_surface(&toplevel) {
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
if let Some(element) = shell.element_for_surface(&toplevel) {
|
||||
if element.has_active_window(&toplevel) {
|
||||
if let Some(workspace) = self.common.shell.space_for(element) {
|
||||
if let Some(workspace) = shell.space_for(element) {
|
||||
if let Some(geometry) = workspace.element_geometry(element) {
|
||||
let mut surface_geo = element.active_window_geometry().as_local();
|
||||
surface_geo.loc += geometry.loc;
|
||||
|
|
@ -268,12 +279,20 @@ impl ScreencopyHandler for State {
|
|||
return;
|
||||
}
|
||||
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
let seat = self
|
||||
.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.seats
|
||||
.last_active()
|
||||
.clone();
|
||||
render_cursor_to_buffer(self, &session, frame, &seat);
|
||||
}
|
||||
|
||||
fn frame_aborted(&mut self, frame: Frame) {
|
||||
for mut output in self.common.shell.outputs().cloned() {
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
for mut output in shell.outputs().cloned() {
|
||||
output.remove_frame(&frame)
|
||||
}
|
||||
}
|
||||
|
|
@ -286,7 +305,13 @@ impl ScreencopyHandler for State {
|
|||
}
|
||||
}
|
||||
ImageSourceData::Workspace(handle) => {
|
||||
if let Some(workspace) = self.common.shell.workspaces.space_for_handle_mut(&handle)
|
||||
if let Some(workspace) = self
|
||||
.common
|
||||
.shell
|
||||
.write()
|
||||
.unwrap()
|
||||
.workspaces
|
||||
.space_for_handle_mut(&handle)
|
||||
{
|
||||
workspace.remove_session(session)
|
||||
}
|
||||
|
|
@ -304,7 +329,13 @@ impl ScreencopyHandler for State {
|
|||
}
|
||||
}
|
||||
ImageSourceData::Workspace(handle) => {
|
||||
if let Some(workspace) = self.common.shell.workspaces.space_for_handle_mut(&handle)
|
||||
if let Some(workspace) = self
|
||||
.common
|
||||
.shell
|
||||
.write()
|
||||
.unwrap()
|
||||
.workspaces
|
||||
.space_for_handle_mut(&handle)
|
||||
{
|
||||
workspace.remove_cursor_session(session)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,18 +189,16 @@ pub fn render_workspace_to_buffer(
|
|||
#[cfg(feature = "debug")]
|
||||
puffin::profile_function!();
|
||||
|
||||
let Some(workspace) = state.common.shell.workspaces.space_for_handle(&handle) else {
|
||||
let shell = state.common.shell.read().unwrap();
|
||||
let Some(workspace) = shell.workspaces.space_for_handle(&handle) else {
|
||||
session.stop();
|
||||
return;
|
||||
};
|
||||
|
||||
let output = workspace.output().clone();
|
||||
let idx = state
|
||||
.common
|
||||
.shell
|
||||
.workspaces
|
||||
.idx_for_handle(&output, &handle)
|
||||
.unwrap();
|
||||
let idx = shell.workspaces.idx_for_handle(&output, &handle).unwrap();
|
||||
std::mem::drop(shell);
|
||||
|
||||
let mode = output
|
||||
.current_mode()
|
||||
.map(|mode| mode.size.to_logical(1).to_buffer(1, Transform::Normal));
|
||||
|
|
@ -286,7 +284,7 @@ pub fn render_workspace_to_buffer(
|
|||
dt,
|
||||
age,
|
||||
additional_damage,
|
||||
&common.shell,
|
||||
&*common.shell.read().unwrap(),
|
||||
&common.config,
|
||||
&common.theme,
|
||||
common.clock.now(),
|
||||
|
|
@ -314,7 +312,7 @@ pub fn render_workspace_to_buffer(
|
|||
dt,
|
||||
age,
|
||||
additional_damage,
|
||||
&common.shell,
|
||||
&*common.shell.read().unwrap(),
|
||||
&common.config,
|
||||
&common.theme,
|
||||
common.clock.now(),
|
||||
|
|
@ -535,21 +533,23 @@ pub fn render_window_to_buffer(
|
|||
.map(Into::<WindowCaptureElement<R>>::into),
|
||||
);
|
||||
|
||||
let seat = common.shell.seats.last_active().clone();
|
||||
if let Some(location) = {
|
||||
if let Some(mapped) = common.shell.element_for_surface(window) {
|
||||
mapped.cursor_position(&seat).and_then(|mut p| {
|
||||
p -= mapped.active_window_offset().to_f64();
|
||||
if p.x < 0. || p.y < 0. {
|
||||
None
|
||||
} else {
|
||||
Some(p)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} {
|
||||
let shell = common.shell.read().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let location = if let Some(mapped) = shell.element_for_surface(window) {
|
||||
mapped.cursor_position(&seat).and_then(|mut p| {
|
||||
p -= mapped.active_window_offset().to_f64();
|
||||
if p.x < 0. || p.y < 0. {
|
||||
None
|
||||
} else {
|
||||
Some(p)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
std::mem::drop(shell);
|
||||
|
||||
if let Some(location) = location {
|
||||
if draw_cursor {
|
||||
elements.extend(
|
||||
cursor::draw_cursor(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ impl SelectionHandler for State {
|
|||
) {
|
||||
if let Some(xwm) = self
|
||||
.common
|
||||
.shell
|
||||
.xwayland_state
|
||||
.as_mut()
|
||||
.and_then(|xstate| xstate.xwm.as_mut())
|
||||
|
|
@ -45,7 +44,6 @@ impl SelectionHandler for State {
|
|||
) {
|
||||
if let Some(xwm) = self
|
||||
.common
|
||||
.shell
|
||||
.xwayland_state
|
||||
.as_mut()
|
||||
.and_then(|xstate| xstate.xwm.as_mut())
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ impl SessionLockHandler for State {
|
|||
}
|
||||
|
||||
fn lock(&mut self, locker: SessionLocker) {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
|
||||
// Reject lock if sesion lock exists and is still valid
|
||||
if let Some(session_lock) = self.common.shell.session_lock.as_ref() {
|
||||
if let Some(session_lock) = shell.session_lock.as_ref() {
|
||||
if self
|
||||
.common
|
||||
.display_handle
|
||||
|
|
@ -32,28 +34,30 @@ impl SessionLockHandler for State {
|
|||
|
||||
let ext_session_lock = locker.ext_session_lock().clone();
|
||||
locker.lock();
|
||||
self.common.shell.session_lock = Some(SessionLock {
|
||||
shell.session_lock = Some(SessionLock {
|
||||
ext_session_lock,
|
||||
surfaces: HashMap::new(),
|
||||
});
|
||||
|
||||
for output in self.common.shell.outputs() {
|
||||
for output in shell.outputs() {
|
||||
self.backend
|
||||
.schedule_render(&self.common.event_loop_handle, &output);
|
||||
}
|
||||
}
|
||||
|
||||
fn unlock(&mut self) {
|
||||
self.common.shell.session_lock = None;
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
shell.session_lock = None;
|
||||
|
||||
for output in self.common.shell.outputs() {
|
||||
for output in shell.outputs() {
|
||||
self.backend
|
||||
.schedule_render(&self.common.event_loop_handle, &output);
|
||||
}
|
||||
}
|
||||
|
||||
fn new_surface(&mut self, lock_surface: LockSurface, wl_output: WlOutput) {
|
||||
if let Some(session_lock) = &mut self.common.shell.session_lock {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(session_lock) = &mut shell.session_lock {
|
||||
if let Some(output) = Output::from_resource(&wl_output) {
|
||||
lock_surface.with_pending_state(|states| {
|
||||
let size = output.geometry().size;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ impl ToplevelInfoHandler for State {
|
|||
type Window = CosmicSurface;
|
||||
|
||||
fn toplevel_info_state(&self) -> &ToplevelInfoState<State, Self::Window> {
|
||||
&self.common.shell.toplevel_info_state
|
||||
&self.common.toplevel_info_state
|
||||
}
|
||||
fn toplevel_info_state_mut(&mut self) -> &mut ToplevelInfoState<State, Self::Window> {
|
||||
&mut self.common.shell.toplevel_info_state
|
||||
&mut self.common.toplevel_info_state
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ use crate::{
|
|||
wayland::protocols::{
|
||||
toplevel_info::ToplevelInfoHandler,
|
||||
toplevel_management::{
|
||||
delegate_toplevel_management, ManagementWindow, ToplevelManagementHandler,
|
||||
ToplevelManagementState,
|
||||
delegate_toplevel_management, toplevel_rectangle_for, ManagementWindow,
|
||||
ToplevelManagementHandler, ToplevelManagementState,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
impl ToplevelManagementHandler for State {
|
||||
fn toplevel_management_state(&mut self) -> &mut ToplevelManagementState {
|
||||
&mut self.common.shell.toplevel_management_state
|
||||
&mut self.common.toplevel_management_state
|
||||
}
|
||||
|
||||
fn activate(
|
||||
|
|
@ -33,17 +33,10 @@ impl ToplevelManagementHandler for State {
|
|||
seat: Option<Seat<Self>>,
|
||||
) {
|
||||
self.unminimize(dh, window);
|
||||
for output in self
|
||||
.common
|
||||
.shell
|
||||
.outputs()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
.iter()
|
||||
{
|
||||
let maybe = self
|
||||
.common
|
||||
.shell
|
||||
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
for output in shell.outputs().cloned().collect::<Vec<_>>().iter() {
|
||||
let maybe = shell
|
||||
.workspaces
|
||||
.spaces_for_output(output)
|
||||
.enumerate()
|
||||
|
|
@ -53,19 +46,22 @@ impl ToplevelManagementHandler for State {
|
|||
.any(|w| &w == window)
|
||||
});
|
||||
if let Some((idx, workspace)) = maybe {
|
||||
let seat = seat.unwrap_or(self.common.shell.seats.last_active().clone());
|
||||
let seat = seat.unwrap_or(shell.seats.last_active().clone());
|
||||
let mapped = workspace
|
||||
.mapped()
|
||||
.find(|m| m.windows().any(|(w, _)| &w == window))
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
let _ = self.common.shell.activate(
|
||||
let _ = shell.activate(
|
||||
&output,
|
||||
idx as usize,
|
||||
WorkspaceDelta::new_shortcut(),
|
||||
&mut self.common.workspace_state.update(),
|
||||
); // TODO: Move pointer?
|
||||
mapped.focus_window(window);
|
||||
|
||||
std::mem::drop(shell);
|
||||
Shell::set_focus(self, Some(&mapped.clone().into()), &seat, None);
|
||||
return;
|
||||
}
|
||||
|
|
@ -83,16 +79,12 @@ impl ToplevelManagementHandler for State {
|
|||
workspace: ZcosmicWorkspaceHandleV1,
|
||||
_output: Output,
|
||||
) {
|
||||
let Some(to_handle) = self
|
||||
.common
|
||||
.shell
|
||||
.workspace_state
|
||||
.get_workspace_handle(&workspace)
|
||||
else {
|
||||
let Some(to_handle) = self.common.workspace_state.get_workspace_handle(&workspace) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let from_workspace = self.common.shell.workspaces.spaces().find(|w| {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let from_workspace = shell.workspaces.spaces().find(|w| {
|
||||
w.mapped()
|
||||
.flat_map(|m| m.windows().map(|(s, _)| s))
|
||||
.any(|w| &w == window)
|
||||
|
|
@ -104,15 +96,18 @@ impl ToplevelManagementHandler for State {
|
|||
.unwrap()
|
||||
.clone();
|
||||
let from_handle = from_workspace.handle;
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
if let Some((target, _)) = self.common.shell.move_window(
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let res = shell.move_window(
|
||||
Some(&seat),
|
||||
&mapped,
|
||||
&from_handle,
|
||||
&to_handle,
|
||||
false,
|
||||
None,
|
||||
) {
|
||||
&mut self.common.workspace_state.update(),
|
||||
);
|
||||
if let Some((target, _)) = res {
|
||||
std::mem::drop(shell);
|
||||
Shell::set_focus(self, Some(&target), &seat, None);
|
||||
}
|
||||
return;
|
||||
|
|
@ -125,29 +120,19 @@ impl ToplevelManagementHandler for State {
|
|||
window: &<Self as ToplevelInfoHandler>::Window,
|
||||
output: Option<Output>,
|
||||
) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(window).cloned() {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
if let Some(mapped) = shell.element_for_surface(window).cloned() {
|
||||
if let Some(output) = output {
|
||||
let from = self
|
||||
.common
|
||||
.shell
|
||||
.toplevel_management_state
|
||||
.minimize_rectangle(&output, window);
|
||||
let workspace = self.common.shell.workspaces.active_mut(&output);
|
||||
let from = minimize_rectangle(&output, window);
|
||||
let workspace = shell.workspaces.active_mut(&output);
|
||||
workspace.fullscreen_request(window, None, from, &seat);
|
||||
} else if let Some((output, handle)) = self
|
||||
.common
|
||||
.shell
|
||||
} else if let Some((output, handle)) = shell
|
||||
.space_for(&mapped)
|
||||
.map(|workspace| (workspace.output.clone(), workspace.handle.clone()))
|
||||
{
|
||||
let from = self
|
||||
.common
|
||||
.shell
|
||||
.toplevel_management_state
|
||||
.minimize_rectangle(&output, window);
|
||||
self.common
|
||||
.shell
|
||||
let from = minimize_rectangle(&output, window);
|
||||
shell
|
||||
.workspaces
|
||||
.space_for_handle_mut(&handle)
|
||||
.unwrap()
|
||||
|
|
@ -161,20 +146,19 @@ impl ToplevelManagementHandler for State {
|
|||
_dh: &DisplayHandle,
|
||||
window: &<Self as ToplevelInfoHandler>::Window,
|
||||
) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(window).cloned() {
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(window).cloned() {
|
||||
if let Some(workspace) = shell.space_for_mut(&mapped) {
|
||||
if let Some((layer, previous_workspace)) = workspace.unfullscreen_request(window) {
|
||||
let old_handle = workspace.handle.clone();
|
||||
let new_workspace_handle = self
|
||||
.common
|
||||
.shell
|
||||
let new_workspace_handle = shell
|
||||
.workspaces
|
||||
.space_for_handle(&previous_workspace)
|
||||
.is_some()
|
||||
.then_some(previous_workspace)
|
||||
.unwrap_or(old_handle); // if the workspace doesn't exist anymore, we can still remap on the right layer
|
||||
|
||||
self.common.shell.remap_unfullscreened_window(
|
||||
shell.remap_unfullscreened_window(
|
||||
mapped,
|
||||
&old_handle,
|
||||
&new_workspace_handle,
|
||||
|
|
@ -186,30 +170,34 @@ impl ToplevelManagementHandler for State {
|
|||
}
|
||||
|
||||
fn maximize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(window).cloned() {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
self.common.shell.maximize_request(&mapped, &seat);
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(window).cloned() {
|
||||
let seat = shell.seats.last_active().clone();
|
||||
shell.maximize_request(&mapped, &seat);
|
||||
}
|
||||
}
|
||||
|
||||
fn unmaximize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(window).cloned() {
|
||||
self.common.shell.unmaximize_request(&mapped);
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(window).cloned() {
|
||||
shell.unmaximize_request(&mapped);
|
||||
}
|
||||
}
|
||||
|
||||
fn minimize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(window).cloned() {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(window).cloned() {
|
||||
if !mapped.is_stack() || &mapped.active_window() == window {
|
||||
self.common.shell.minimize_request(&mapped);
|
||||
shell.minimize_request(&mapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn unminimize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
|
||||
if let Some(mut mapped) = self.common.shell.element_for_surface(window).cloned() {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
self.common.shell.unminimize_request(&mapped, &seat);
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mut mapped) = shell.element_for_surface(window).cloned() {
|
||||
let seat = shell.seats.last_active().clone();
|
||||
shell.unminimize_request(&mapped, &seat);
|
||||
if mapped.is_stack() {
|
||||
mapped.stack_ref_mut().unwrap().set_active(window);
|
||||
}
|
||||
|
|
@ -223,43 +211,29 @@ impl ManagementWindow for CosmicSurface {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait ToplevelManagementExt {
|
||||
fn minimize_rectangle(
|
||||
&mut self,
|
||||
output: &Output,
|
||||
window: &CosmicSurface,
|
||||
) -> Rectangle<i32, Local>;
|
||||
}
|
||||
|
||||
impl ToplevelManagementExt for ToplevelManagementState {
|
||||
fn minimize_rectangle(
|
||||
&mut self,
|
||||
output: &Output,
|
||||
window: &CosmicSurface,
|
||||
) -> Rectangle<i32, Local> {
|
||||
self.rectangle_for(window)
|
||||
.find_map(|(surface, relative)| {
|
||||
let map = layer_map_for_output(output);
|
||||
let layer = map.layer_for_surface(&surface, WindowSurfaceType::ALL);
|
||||
layer.and_then(|s| map.layer_geometry(s)).map(|local| {
|
||||
Rectangle::from_loc_and_size(
|
||||
Point::from((local.loc.x + relative.loc.x, local.loc.y + relative.loc.y)),
|
||||
relative.size,
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
let output_size = output.geometry().size;
|
||||
pub fn minimize_rectangle(output: &Output, window: &CosmicSurface) -> Rectangle<i32, Local> {
|
||||
toplevel_rectangle_for(window)
|
||||
.find_map(|(surface, relative)| {
|
||||
let map = layer_map_for_output(output);
|
||||
let layer = map.layer_for_surface(&surface, WindowSurfaceType::ALL);
|
||||
layer.and_then(|s| map.layer_geometry(s)).map(|local| {
|
||||
Rectangle::from_loc_and_size(
|
||||
Point::from((
|
||||
(output_size.w / 2) - 100,
|
||||
output_size.h - (output_size.h / 3) - 50,
|
||||
)),
|
||||
Size::from((200, 100)),
|
||||
Point::from((local.loc.x + relative.loc.x, local.loc.y + relative.loc.y)),
|
||||
relative.size,
|
||||
)
|
||||
})
|
||||
.as_local()
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
let output_size = output.geometry().size;
|
||||
Rectangle::from_loc_and_size(
|
||||
Point::from((
|
||||
(output_size.w / 2) - 100,
|
||||
output_size.h - (output_size.h / 3) - 50,
|
||||
)),
|
||||
Size::from((200, 100)),
|
||||
)
|
||||
})
|
||||
.as_local()
|
||||
}
|
||||
|
||||
delegate_toplevel_management!(State);
|
||||
|
|
|
|||
|
|
@ -21,17 +21,18 @@ impl WorkspaceClientHandler for ClientState {
|
|||
impl WorkspaceHandler for State {
|
||||
type Client = ClientState;
|
||||
fn workspace_state(&self) -> &WorkspaceState<Self> {
|
||||
&self.common.shell.workspace_state
|
||||
&self.common.workspace_state
|
||||
}
|
||||
fn workspace_state_mut(&mut self) -> &mut WorkspaceState<Self> {
|
||||
&mut self.common.shell.workspace_state
|
||||
&mut self.common.workspace_state
|
||||
}
|
||||
|
||||
fn commit_requests(&mut self, _dh: &DisplayHandle, requests: Vec<Request>) {
|
||||
for request in requests.into_iter() {
|
||||
match request {
|
||||
Request::Activate(handle) => {
|
||||
let maybe = self.common.shell.workspaces.iter().find_map(|(o, set)| {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let maybe = shell.workspaces.iter().find_map(|(o, set)| {
|
||||
set.workspaces
|
||||
.iter()
|
||||
.position(|w| w.handle == handle)
|
||||
|
|
@ -39,22 +40,20 @@ impl WorkspaceHandler for State {
|
|||
});
|
||||
|
||||
if let Some((output, idx)) = maybe {
|
||||
let _ = self.common.shell.activate(
|
||||
let _ = shell.activate(
|
||||
&output,
|
||||
idx,
|
||||
WorkspaceDelta::new_shortcut(),
|
||||
); // TODO: move cursor?
|
||||
&mut self.common.workspace_state.update(),
|
||||
);
|
||||
// TODO: move cursor?
|
||||
}
|
||||
}
|
||||
Request::SetTilingState { workspace, state } => {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
if let Some(workspace) = self
|
||||
.common
|
||||
.shell
|
||||
.workspaces
|
||||
.space_for_handle_mut(&workspace)
|
||||
{
|
||||
let mut guard = self.common.shell.workspace_state.update();
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
if let Some(workspace) = shell.workspaces.space_for_handle_mut(&workspace) {
|
||||
let mut guard = self.common.workspace_state.update();
|
||||
workspace.set_tiling(
|
||||
match state.into_result() {
|
||||
Ok(TilingState::FloatingOnly) => false,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
use crate::{shell::ActivationKey, state::ClientState, utils::prelude::*};
|
||||
use crate::{state::State, wayland::protocols::workspace::WorkspaceHandle};
|
||||
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState;
|
||||
use smithay::{
|
||||
delegate_xdg_activation,
|
||||
input::Seat,
|
||||
|
|
@ -8,9 +11,6 @@ use smithay::{
|
|||
};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{shell::ActivationKey, state::ClientState, utils::prelude::*};
|
||||
use crate::{state::State, wayland::protocols::workspace::WorkspaceHandle};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ActivationContext {
|
||||
UrgentOnly,
|
||||
|
|
@ -19,7 +19,7 @@ pub enum ActivationContext {
|
|||
|
||||
impl XdgActivationHandler for State {
|
||||
fn activation_state(&mut self) -> &mut XdgActivationState {
|
||||
&mut self.common.shell.xdg_activation_state
|
||||
&mut self.common.xdg_activation_state
|
||||
}
|
||||
|
||||
fn token_created(&mut self, token: XdgActivationToken, data: XdgActivationTokenData) -> bool {
|
||||
|
|
@ -41,7 +41,8 @@ impl XdgActivationHandler for State {
|
|||
{
|
||||
if let Some(seat) = data.serial.and_then(|(_, seat)| Seat::from_resource(&seat)) {
|
||||
let output = seat.active_output();
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let workspace = shell.active_space_mut(&output);
|
||||
workspace.pending_tokens.insert(token.clone());
|
||||
let handle = workspace.handle;
|
||||
data.user_data
|
||||
|
|
@ -84,7 +85,8 @@ impl XdgActivationHandler for State {
|
|||
|
||||
if valid {
|
||||
let output = seat.active_output();
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let workspace = shell.active_space_mut(&output);
|
||||
workspace.pending_tokens.insert(token.clone());
|
||||
let handle = workspace.handle;
|
||||
data.user_data
|
||||
|
|
@ -105,24 +107,24 @@ impl XdgActivationHandler for State {
|
|||
surface: WlSurface,
|
||||
) {
|
||||
if let Some(context) = token_data.user_data.get::<ActivationContext>() {
|
||||
if let Some(element) = self.common.shell.element_for_surface(&surface).cloned() {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(element) = shell.element_for_surface(&surface).cloned() {
|
||||
match context {
|
||||
ActivationContext::UrgentOnly => {
|
||||
if let Some((workspace, _output)) =
|
||||
self.common.shell.workspace_for_surface(&surface)
|
||||
{
|
||||
self.common.shell.set_urgent(&workspace);
|
||||
if let Some((workspace, _output)) = shell.workspace_for_surface(&surface) {
|
||||
let mut workspace_guard = self.common.workspace_state.update();
|
||||
workspace_guard.add_workspace_state(&workspace, WState::Urgent);
|
||||
}
|
||||
}
|
||||
ActivationContext::Workspace(workspace) => {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let current_output = seat.active_output();
|
||||
|
||||
if element.is_minimized() {
|
||||
self.common.shell.unminimize_request(&element, &seat);
|
||||
shell.unminimize_request(&element, &seat);
|
||||
}
|
||||
|
||||
let current_workspace = self.common.shell.active_space_mut(¤t_output);
|
||||
let current_workspace = shell.active_space_mut(¤t_output);
|
||||
|
||||
let in_current_workspace = current_workspace
|
||||
.floating_layer
|
||||
|
|
@ -152,21 +154,19 @@ impl XdgActivationHandler for State {
|
|||
|
||||
if workspace == ¤t_workspace.handle || in_current_workspace {
|
||||
let target = element.into();
|
||||
|
||||
std::mem::drop(shell);
|
||||
Shell::set_focus(self, Some(&target), &seat, None);
|
||||
} else if let Some(w) = self
|
||||
.common
|
||||
.shell
|
||||
.space_for(&element)
|
||||
.map(|w| w.handle.clone())
|
||||
} else if let Some(w) = shell.space_for(&element).map(|w| w.handle.clone())
|
||||
{
|
||||
self.common.shell.append_focus_stack(&element, &seat);
|
||||
self.common.shell.set_urgent(&w);
|
||||
shell.append_focus_stack(&element, &seat);
|
||||
let mut workspace_guard = self.common.workspace_state.update();
|
||||
workspace_guard.add_workspace_state(&w, WState::Urgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.common
|
||||
.shell
|
||||
shell
|
||||
.pending_activations
|
||||
.insert(ActivationKey::Wayland(surface), context.clone());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use crate::{
|
||||
shell::{element::CosmicWindow, grabs::ReleaseMode, CosmicMapped, CosmicSurface, ManagedLayer},
|
||||
utils::prelude::*,
|
||||
wayland::protocols::toplevel_info::{toplevel_enter_output, toplevel_enter_workspace},
|
||||
};
|
||||
use smithay::{
|
||||
delegate_xdg_shell,
|
||||
|
|
@ -29,7 +30,7 @@ use smithay::{
|
|||
use std::cell::Cell;
|
||||
use tracing::warn;
|
||||
|
||||
use super::{compositor::client_compositor_state, toplevel_management::ToplevelManagementExt};
|
||||
use super::{compositor::client_compositor_state, toplevel_management::minimize_rectangle};
|
||||
|
||||
pub mod popup;
|
||||
|
||||
|
|
@ -37,13 +38,14 @@ pub type PopupGrabData = Cell<Option<PopupGrab<State>>>;
|
|||
|
||||
impl XdgShellHandler for State {
|
||||
fn xdg_shell_state(&mut self) -> &mut XdgShellState {
|
||||
&mut self.common.shell.xdg_shell_state
|
||||
&mut self.common.xdg_shell_state
|
||||
}
|
||||
|
||||
fn new_toplevel(&mut self, surface: ToplevelSurface) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let window = CosmicSurface::from(surface);
|
||||
self.common.shell.pending_windows.push((window, seat, None));
|
||||
shell.pending_windows.push((window, seat, None));
|
||||
// We will position the window after the first commit, when we know its size hints
|
||||
}
|
||||
|
||||
|
|
@ -55,11 +57,14 @@ impl XdgShellHandler for State {
|
|||
|
||||
if surface.get_parent_surface().is_some() {
|
||||
// let other shells deal with their popups
|
||||
self.common.shell.unconstrain_popup(&surface);
|
||||
self.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.unconstrain_popup(&surface);
|
||||
|
||||
if surface.send_configure().is_ok() {
|
||||
self.common
|
||||
.shell
|
||||
.popups
|
||||
.track_popup(PopupKind::from(surface))
|
||||
.unwrap();
|
||||
|
|
@ -70,16 +75,18 @@ impl XdgShellHandler for State {
|
|||
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
|
||||
let seat = Seat::from_resource(&seat).unwrap();
|
||||
let kind = PopupKind::Xdg(surface);
|
||||
if let Some(root) = find_popup_root_surface(&kind)
|
||||
.ok()
|
||||
.and_then(|root| self.common.shell.element_for_surface(&root))
|
||||
{
|
||||
let target = root.clone().into();
|
||||
let ret = self
|
||||
.common
|
||||
let maybe_root = find_popup_root_surface(&kind).ok().and_then(|root| {
|
||||
self.common
|
||||
.shell
|
||||
.popups
|
||||
.grab_popup(target, kind, &seat, serial);
|
||||
.read()
|
||||
.unwrap()
|
||||
.element_for_surface(&root)
|
||||
.cloned()
|
||||
});
|
||||
|
||||
if let Some(root) = maybe_root {
|
||||
let target = root.into();
|
||||
let ret = self.common.popups.grab_popup(target, kind, &seat, serial);
|
||||
|
||||
if let Ok(mut grab) = ret {
|
||||
if let Some(keyboard) = seat.get_keyboard() {
|
||||
|
|
@ -128,7 +135,11 @@ impl XdgShellHandler for State {
|
|||
state.positioner = positioner;
|
||||
});
|
||||
|
||||
self.common.shell.unconstrain_popup(&surface);
|
||||
self.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.unconstrain_popup(&surface);
|
||||
surface.send_repositioned(token);
|
||||
if let Err(err) = surface.send_configure() {
|
||||
warn!(
|
||||
|
|
@ -140,14 +151,26 @@ impl XdgShellHandler for State {
|
|||
|
||||
fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
|
||||
let seat = Seat::from_resource(&seat).unwrap();
|
||||
Shell::move_request(
|
||||
self,
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some((grab, focus)) = shell.move_request(
|
||||
surface.wl_surface(),
|
||||
&seat,
|
||||
serial,
|
||||
ReleaseMode::NoMouseButtons,
|
||||
false,
|
||||
)
|
||||
&self.common.config,
|
||||
&self.common.event_loop_handle,
|
||||
&self.common.xdg_activation_state,
|
||||
) {
|
||||
std::mem::drop(shell);
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(self, grab, serial);
|
||||
} else {
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(self, grab, serial, focus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resize_request(
|
||||
|
|
@ -158,70 +181,60 @@ impl XdgShellHandler for State {
|
|||
edges: xdg_toplevel::ResizeEdge,
|
||||
) {
|
||||
let seat = Seat::from_resource(&seat).unwrap();
|
||||
Shell::resize_request(self, surface.wl_surface(), &seat, serial, edges.into())
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some((grab, focus)) =
|
||||
shell.resize_request(surface.wl_surface(), &seat, serial, edges.into())
|
||||
{
|
||||
std::mem::drop(shell);
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(self, grab, serial)
|
||||
} else {
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(self, grab, serial, focus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn minimize_request(&mut self, surface: ToplevelSurface) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
|
||||
if !mapped.is_stack()
|
||||
|| mapped.active_window().wl_surface().as_ref() == Some(surface.wl_surface())
|
||||
{
|
||||
self.common.shell.minimize_request(&mapped)
|
||||
shell.minimize_request(&mapped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
self.common.shell.maximize_request(&mapped, &seat)
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
|
||||
let seat = shell.seats.last_active().clone();
|
||||
shell.maximize_request(&mapped, &seat)
|
||||
}
|
||||
}
|
||||
|
||||
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
self.common.shell.unmaximize_request(&mapped);
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
|
||||
shell.unmaximize_request(&mapped);
|
||||
}
|
||||
}
|
||||
|
||||
fn fullscreen_request(&mut self, surface: ToplevelSurface, output: Option<WlOutput>) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
let active_output = seat.active_output();
|
||||
let output = output
|
||||
.as_ref()
|
||||
.and_then(Output::from_resource)
|
||||
.unwrap_or_else(|| active_output.clone());
|
||||
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
let from = self
|
||||
.common
|
||||
.shell
|
||||
.toplevel_management_state
|
||||
.minimize_rectangle(&output, &mapped.active_window());
|
||||
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
|
||||
let from = minimize_rectangle(&output, &mapped.active_window());
|
||||
|
||||
if let Some(set) = self
|
||||
.common
|
||||
.shell
|
||||
if let Some(set) = shell
|
||||
.workspaces
|
||||
.sets
|
||||
.values_mut()
|
||||
|
|
@ -248,19 +261,13 @@ impl XdgShellHandler for State {
|
|||
mapped
|
||||
};
|
||||
|
||||
let workspace_handle = self.common.shell.active_space(&output).handle.clone();
|
||||
let workspace_handle = shell.active_space(&output).handle.clone();
|
||||
for (window, _) in mapped.windows() {
|
||||
self.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_enter_output(&window, &output);
|
||||
self.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_enter_workspace(&window, &workspace_handle);
|
||||
toplevel_enter_output(&window, &output);
|
||||
toplevel_enter_workspace(&window, &workspace_handle);
|
||||
}
|
||||
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let workspace = shell.active_space_mut(&output);
|
||||
workspace.floating_layer.map(mapped.clone(), None);
|
||||
|
||||
workspace.fullscreen_request(
|
||||
|
|
@ -269,7 +276,7 @@ impl XdgShellHandler for State {
|
|||
from,
|
||||
&seat,
|
||||
);
|
||||
} else if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
} else if let Some(workspace) = shell.space_for_mut(&mapped) {
|
||||
if workspace.output != output {
|
||||
let (mapped, layer) = if mapped
|
||||
.stack_ref()
|
||||
|
|
@ -300,19 +307,13 @@ impl XdgShellHandler for State {
|
|||
};
|
||||
let handle = workspace.handle.clone();
|
||||
|
||||
let workspace_handle = self.common.shell.active_space(&output).handle.clone();
|
||||
let workspace_handle = shell.active_space(&output).handle.clone();
|
||||
for (window, _) in mapped.windows() {
|
||||
self.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_enter_output(&window, &output);
|
||||
self.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_enter_workspace(&window, &workspace_handle);
|
||||
toplevel_enter_output(&window, &output);
|
||||
toplevel_enter_workspace(&window, &workspace_handle);
|
||||
}
|
||||
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let workspace = shell.active_space_mut(&output);
|
||||
workspace.floating_layer.map(mapped.clone(), None);
|
||||
|
||||
workspace.fullscreen_request(
|
||||
|
|
@ -330,9 +331,7 @@ impl XdgShellHandler for State {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(o) = self
|
||||
.common
|
||||
.shell
|
||||
if let Some(o) = shell
|
||||
.pending_windows
|
||||
.iter_mut()
|
||||
.find(|(s, _, _)| s.wl_surface().as_ref() == Some(surface.wl_surface()))
|
||||
|
|
@ -344,29 +343,23 @@ impl XdgShellHandler for State {
|
|||
}
|
||||
|
||||
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
|
||||
if let Some(workspace) = shell.space_for_mut(&mapped) {
|
||||
let (window, _) = mapped
|
||||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
|
||||
.unwrap();
|
||||
if let Some((layer, previous_workspace)) = workspace.unfullscreen_request(&window) {
|
||||
let old_handle = workspace.handle.clone();
|
||||
let new_workspace_handle = self
|
||||
.common
|
||||
.shell
|
||||
let new_workspace_handle = shell
|
||||
.workspaces
|
||||
.space_for_handle(&previous_workspace)
|
||||
.is_some()
|
||||
.then_some(previous_workspace)
|
||||
.unwrap_or(old_handle); // if the workspace doesn't exist anymore, we can still remap on the right layer
|
||||
|
||||
self.common.shell.remap_unfullscreened_window(
|
||||
shell.remap_unfullscreened_window(
|
||||
mapped,
|
||||
&old_handle,
|
||||
&new_workspace_handle,
|
||||
|
|
@ -378,20 +371,26 @@ impl XdgShellHandler for State {
|
|||
}
|
||||
|
||||
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
|
||||
let seat = self.common.shell.seats.last_active().clone();
|
||||
self.common.shell.unmap_surface(surface.wl_surface(), &seat);
|
||||
let (output, clients) = {
|
||||
let mut shell = self.common.shell.write().unwrap();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
shell.unmap_surface(
|
||||
surface.wl_surface(),
|
||||
&seat,
|
||||
&mut self.common.toplevel_info_state,
|
||||
);
|
||||
|
||||
let output = self
|
||||
.common
|
||||
.shell
|
||||
.visible_output_for_surface(surface.wl_surface())
|
||||
.cloned();
|
||||
if let Some(output) = output.as_ref() {
|
||||
self.common.shell.refresh_active_space(output);
|
||||
}
|
||||
let output = shell
|
||||
.visible_output_for_surface(surface.wl_surface())
|
||||
.cloned();
|
||||
if let Some(output) = output.as_ref() {
|
||||
shell.refresh_active_space(output, &self.common.xdg_activation_state);
|
||||
}
|
||||
|
||||
// animations might be unblocked now
|
||||
(output, shell.update_animations())
|
||||
};
|
||||
|
||||
// animations might be unblocked now
|
||||
let clients = self.common.shell.update_animations();
|
||||
{
|
||||
let dh = self.common.display_handle.clone();
|
||||
for client in clients.values() {
|
||||
|
|
@ -418,7 +417,23 @@ impl XdgShellHandler for State {
|
|||
})
|
||||
.unwrap_or_default()
|
||||
.loc;
|
||||
Shell::menu_request(self, surface.wl_surface(), &seat, serial, location, false)
|
||||
|
||||
let shell = self.common.shell.read().unwrap();
|
||||
let res = shell.menu_request(
|
||||
surface.wl_surface(),
|
||||
&seat,
|
||||
serial,
|
||||
location,
|
||||
false,
|
||||
&self.common.config,
|
||||
&self.common.event_loop_handle,
|
||||
);
|
||||
if let Some((grab, focus)) = res {
|
||||
std::mem::drop(shell);
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(self, grab, serial, focus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ impl XWaylandKeyboardGrabHandler for State {
|
|||
let element = self
|
||||
.common
|
||||
.shell
|
||||
.read()
|
||||
.unwrap()
|
||||
.workspaces
|
||||
.spaces()
|
||||
.find_map(|x| x.element_for_surface(surface))?;
|
||||
Some(KeyboardFocusTarget::Element(element.clone()))
|
||||
.find_map(|x| x.element_for_surface(surface).cloned())?;
|
||||
Some(KeyboardFocusTarget::Element(element))
|
||||
}
|
||||
}
|
||||
delegate_xwayland_keyboard_grab!(State);
|
||||
|
|
|
|||
|
|
@ -185,6 +185,30 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_enter_output(toplevel: &impl Window, output: &Output) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().outputs.push(output.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_leave_output(toplevel: &impl Window, output: &Output) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().outputs.retain(|o| o != output);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_enter_workspace(toplevel: &impl Window, workspace: &WorkspaceHandle) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().workspaces.push(workspace.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_leave_workspace(toplevel: &impl Window, workspace: &WorkspaceHandle) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().workspaces.retain(|w| w != workspace);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D, W> ToplevelInfoState<D, W>
|
||||
where
|
||||
D: GlobalDispatch<ZcosmicToplevelInfoV1, ToplevelInfoGlobalData>
|
||||
|
|
@ -223,30 +247,6 @@ where
|
|||
self.toplevels.push(toplevel.clone());
|
||||
}
|
||||
|
||||
pub fn toplevel_enter_output(&mut self, toplevel: &W, output: &Output) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().outputs.push(output.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_leave_output(&mut self, toplevel: &W, output: &Output) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().outputs.retain(|o| o != output);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_enter_workspace(&mut self, toplevel: &W, workspace: &WorkspaceHandle) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().workspaces.push(workspace.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_leave_workspace(&mut self, toplevel: &W, workspace: &WorkspaceHandle) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().workspaces.retain(|w| w != workspace);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_toplevel(&mut self, toplevel: &W) {
|
||||
if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
let mut state_inner = state.lock().unwrap();
|
||||
|
|
|
|||
|
|
@ -71,6 +71,29 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_rectangle_for(
|
||||
window: &impl ManagementWindow,
|
||||
) -> impl Iterator<Item = (WlSurface, Rectangle<i32, Logical>)> {
|
||||
if let Some(state) = window.user_data().get::<ToplevelState>() {
|
||||
let mut state = state.lock().unwrap();
|
||||
state
|
||||
.rectangles
|
||||
.retain(|(surface, _)| surface.upgrade().is_ok());
|
||||
Some(
|
||||
state
|
||||
.rectangles
|
||||
.iter()
|
||||
.map(|(surface, rect)| (surface.upgrade().unwrap(), *rect))
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter(),
|
||||
)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
} else {
|
||||
None.into_iter().flatten()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ToplevelManagerGlobalData {
|
||||
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
|
||||
}
|
||||
|
|
@ -102,30 +125,6 @@ impl ToplevelManagementState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn rectangle_for(
|
||||
&mut self,
|
||||
window: &impl ManagementWindow,
|
||||
) -> impl Iterator<Item = (WlSurface, Rectangle<i32, Logical>)> {
|
||||
if let Some(state) = window.user_data().get::<ToplevelState>() {
|
||||
let mut state = state.lock().unwrap();
|
||||
state
|
||||
.rectangles
|
||||
.retain(|(surface, _)| surface.upgrade().is_ok());
|
||||
Some(
|
||||
state
|
||||
.rectangles
|
||||
.iter()
|
||||
.map(|(surface, rect)| (surface.upgrade().unwrap(), *rect))
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter(),
|
||||
)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
} else {
|
||||
None.into_iter().flatten()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn global_id(&self) -> GlobalId {
|
||||
self.global.clone()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue