Add XWayland support (#16)
* save dev state * fix xwayland-satellite supervisor lifecycle, readiness and cleanup * remove wayland scanner protocol generated files * default xwayland enabled with path * remove jargons * address x11 review: park unconfirmed cleanup, never signal a reaped group, fix storm test and notify dir mode * fix resize tests: never build Size values from negative dimensions * add min-width/min-height window rules that replace client minimum sizes * rename effective_size_constraints to effective_minimum_size and minor cleanups
This commit is contained in:
1 parent
ed23949a95
commit
a6f83689f8
42 files changed
+7162
-1333
No files matched your search
@@ -11,6 +11,7 @@ mod xdg_shell;
|
||||
use smithay::desktop::{PopupManager, layer_map_for_output};
|
||||
use smithay::input::pointer::{CursorImageStatus, PointerHandle};
|
||||
use smithay::input::{Seat, SeatHandler, SeatState};
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::{xdg_popup, xdg_positioner, xdg_surface, xdg_wm_base};
|
||||
use smithay::reexports::wayland_server::Resource;
|
||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||
use smithay::wayland::compositor::{TraversalAction, with_states, with_surface_tree_downward};
|
||||
@@ -30,6 +31,9 @@ use smithay::wayland::selection::data_device::{
|
||||
use smithay::wayland::selection::primary_selection::{
|
||||
PrimarySelectionHandler, PrimarySelectionState, set_primary_focus,
|
||||
};
|
||||
use smithay::wayland::shell::xdg::{
|
||||
XdgPositionerUserData, XdgShellState, XdgShellSurfaceUserData, XdgSurfaceUserData, XdgWmBaseUserData,
|
||||
};
|
||||
use smithay::wayland::tablet_manager::TabletSeatHandler;
|
||||
use smithay::wayland::xdg_foreign::{XdgForeignHandler, XdgForeignState};
|
||||
use smithay::wayland::xdg_toplevel_icon::XdgToplevelIconHandler;
|
||||
@@ -338,7 +342,21 @@ smithay::delegate_viewporter!(Ferese);
|
||||
smithay::delegate_xdg_activation!(Ferese);
|
||||
smithay::delegate_xdg_decoration!(Ferese);
|
||||
smithay::delegate_xdg_foreign!(Ferese);
|
||||
smithay::delegate_xdg_shell!(Ferese);
|
||||
smithay::reexports::wayland_server::delegate_global_dispatch!(
|
||||
Ferese: [xdg_wm_base::XdgWmBase: ()] => XdgShellState
|
||||
);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!(
|
||||
Ferese: [xdg_wm_base::XdgWmBase: XdgWmBaseUserData] => XdgShellState
|
||||
);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!(
|
||||
Ferese: [xdg_positioner::XdgPositioner: XdgPositionerUserData] => XdgShellState
|
||||
);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!(
|
||||
Ferese: [xdg_popup::XdgPopup: XdgShellSurfaceUserData] => XdgShellState
|
||||
);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!(
|
||||
Ferese: [xdg_surface::XdgSurface: XdgSurfaceUserData] => XdgShellState
|
||||
);
|
||||
smithay::delegate_xdg_toplevel_icon!(Ferese);
|
||||
|
||||
smithay::delegate_data_control!(Ferese);
|
||||
|
||||
@@ -54,9 +54,8 @@ impl Worker {
|
||||
|
||||
fn run(receiver: Receiver<Job>, results: channel::SyncSender<Encoded>) {
|
||||
while let Ok(job) = receiver.recv() {
|
||||
let result = encode(&job);
|
||||
let request = job.request;
|
||||
drop(job);
|
||||
let result = encode(job);
|
||||
// This send cannot block. Each request produces exactly one Encode, so at
|
||||
// most QUEUE_CAPACITY jobs can be queued while one more is being encoded,
|
||||
// and RESULT_QUEUE_CAPACITY is asserted to exceed that. Blocking here
|
||||
@@ -99,8 +98,10 @@ pub(crate) fn sweep_stale_files() {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode(job: &Job) -> Result<PathBuf, String> {
|
||||
fn encode(job: Job) -> Result<PathBuf, String> {
|
||||
let canvas = compose(&job.frames)?;
|
||||
drop(job);
|
||||
|
||||
let png = encode_png(&canvas)?;
|
||||
write_private_file(&png)
|
||||
}
|
||||
@@ -114,6 +115,7 @@ fn encode_png(canvas: &Canvas) -> Result<Vec<u8>, String> {
|
||||
}
|
||||
let image = image::ImageBuffer::<image::Rgba<u8>, _>::from_raw(width, height, canvas.pixels.as_slice())
|
||||
.ok_or("Screenshot buffer does not match its dimensions")?;
|
||||
|
||||
let mut out = Vec::new();
|
||||
let encoder = image::codecs::png::PngEncoder::new_with_quality(
|
||||
std::io::Cursor::new(&mut out),
|
||||
|
||||
@@ -5,15 +5,17 @@ use smithay::desktop::{
|
||||
use smithay::input::Seat;
|
||||
use smithay::input::pointer::{Focus, GrabStartData};
|
||||
use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode;
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::State as ToplevelState;
|
||||
use smithay::reexports::wayland_server::Resource;
|
||||
use smithay::reexports::wayland_server::protocol::wl_seat;
|
||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||
use smithay::reexports::wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, backend::ClientId};
|
||||
use smithay::utils::{Logical, Point, Rectangle, Serial};
|
||||
use smithay::wayland::compositor::with_states;
|
||||
use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler;
|
||||
use smithay::wayland::shell::xdg::{
|
||||
PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState, XdgToplevelSurfaceData,
|
||||
PopupSurface, PositionerState, SurfaceCachedState, ToplevelSurface, XdgShellHandler, XdgShellState,
|
||||
XdgShellSurfaceUserData, XdgToplevelSurfaceData,
|
||||
};
|
||||
|
||||
use crate::Ferese;
|
||||
@@ -467,6 +469,72 @@ fn popup_constraint_target(
|
||||
output
|
||||
}
|
||||
|
||||
impl Dispatch<xdg_toplevel::XdgToplevel, XdgShellSurfaceUserData> for Ferese {
|
||||
fn request(
|
||||
state: &mut Self,
|
||||
client: &Client,
|
||||
resource: &xdg_toplevel::XdgToplevel,
|
||||
request: xdg_toplevel::Request,
|
||||
data: &XdgShellSurfaceUserData,
|
||||
dhandle: &DisplayHandle,
|
||||
data_init: &mut DataInit<'_, Self>,
|
||||
) {
|
||||
let unusable = match &request {
|
||||
xdg_toplevel::Request::SetMinSize { width, height } => {
|
||||
!size_limits_usable(state, resource, (*width, *height), true)
|
||||
}
|
||||
xdg_toplevel::Request::SetMaxSize { width, height } => {
|
||||
!size_limits_usable(state, resource, (*width, *height), false)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if unusable {
|
||||
resource.post_error(xdg_toplevel::Error::InvalidSize, "size limits are unusable");
|
||||
return;
|
||||
}
|
||||
|
||||
<XdgShellState as Dispatch<xdg_toplevel::XdgToplevel, XdgShellSurfaceUserData, Ferese>>::request(
|
||||
state, client, resource, request, data, dhandle, data_init,
|
||||
);
|
||||
}
|
||||
|
||||
fn destroyed(
|
||||
state: &mut Self,
|
||||
client: ClientId,
|
||||
resource: &xdg_toplevel::XdgToplevel,
|
||||
data: &XdgShellSurfaceUserData,
|
||||
) {
|
||||
<XdgShellState as Dispatch<xdg_toplevel::XdgToplevel, XdgShellSurfaceUserData, Ferese>>::destroyed(
|
||||
state, client, resource, data,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn size_limits_usable(
|
||||
state: &Ferese,
|
||||
toplevel: &xdg_toplevel::XdgToplevel,
|
||||
proposed: (i32, i32),
|
||||
minimum: bool,
|
||||
) -> bool {
|
||||
if proposed.0 < 0 || proposed.1 < 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let Some(surface) = state.xdg_shell_state.get_toplevel(toplevel) else {
|
||||
return true;
|
||||
};
|
||||
let (min, max) = with_states(surface.wl_surface(), |states| {
|
||||
let mut cached = states.cached_state.get::<SurfaceCachedState>();
|
||||
let pending = cached.pending();
|
||||
(
|
||||
(pending.min_size.w, pending.min_size.h),
|
||||
(pending.max_size.w, pending.max_size.h),
|
||||
)
|
||||
});
|
||||
let (min, max) = if minimum { (proposed, max) } else { (min, proposed) };
|
||||
(max.0 == 0 || min.0 <= max.0) && (max.1 == 0 || min.1 <= max.1)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_positioner;
|
||||
|
||||
Reference in new issue
Block a user