xwayland: Add initial support
This commit is contained in:
parent
78ffe3a93d
commit
1d28574088
23 changed files with 781 additions and 185 deletions
|
|
@ -19,6 +19,7 @@ use smithay::{
|
|||
},
|
||||
},
|
||||
},
|
||||
xwayland::X11Wm,
|
||||
};
|
||||
use std::sync::Mutex;
|
||||
|
||||
|
|
@ -108,6 +109,7 @@ impl CompositorHandler for State {
|
|||
}
|
||||
|
||||
fn commit(&mut self, surface: &WlSurface) {
|
||||
X11Wm::commit_hook(surface);
|
||||
// first load the buffer for various smithay helper functions
|
||||
on_commit_buffer_handler(surface);
|
||||
|
||||
|
|
@ -134,10 +136,7 @@ impl CompositorHandler for State {
|
|||
return;
|
||||
}
|
||||
}
|
||||
CosmicSurface::X11(_) => {
|
||||
let output = seat.active_output();
|
||||
Shell::map_window(self, &window, &output);
|
||||
}
|
||||
CosmicSurface::X11(_) => {}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +163,7 @@ 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) = self.common.shell.element_for_wl_surface(surface).cloned() {
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&element) {
|
||||
crate::shell::layout::floating::ResizeSurfaceGrab::apply_resize_to_location(
|
||||
element.clone(),
|
||||
|
|
|
|||
|
|
@ -76,13 +76,21 @@ impl State {
|
|||
|
||||
impl XdgDecorationHandler for State {
|
||||
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_wl_surface(toplevel.wl_surface())
|
||||
{
|
||||
State::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()) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_wl_surface(toplevel.wl_surface())
|
||||
{
|
||||
State::request_mode(mapped, toplevel.wl_surface(), mode);
|
||||
} else {
|
||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
||||
|
|
@ -90,7 +98,11 @@ impl XdgDecorationHandler for State {
|
|||
}
|
||||
|
||||
fn unset_mode(&mut self, toplevel: ToplevelSurface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_wl_surface(toplevel.wl_surface())
|
||||
{
|
||||
State::unset_mode(mapped, toplevel.wl_surface())
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +114,7 @@ impl KdeDecorationHandler for State {
|
|||
}
|
||||
|
||||
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(surface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_wl_surface(surface) {
|
||||
let mode = State::new_decoration(mapped, surface);
|
||||
decoration.mode(mode);
|
||||
}
|
||||
|
|
@ -116,7 +128,7 @@ impl KdeDecorationHandler for State {
|
|||
) {
|
||||
if let WEnum::Value(mode) = mode {
|
||||
// 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) {
|
||||
if let Some(mapped) = self.common.shell.element_for_wl_surface(surface) {
|
||||
State::request_mode(
|
||||
mapped,
|
||||
surface,
|
||||
|
|
@ -131,7 +143,7 @@ impl KdeDecorationHandler for State {
|
|||
}
|
||||
|
||||
fn release(&mut self, _decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(surface) {
|
||||
if let Some(mapped) = self.common.shell.element_for_wl_surface(surface) {
|
||||
State::unset_mode(mapped, surface)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -890,10 +890,7 @@ pub fn render_window_to_buffer(
|
|||
for seat in common.seats() {
|
||||
if let Some(location) = {
|
||||
// we need to find the mapped element in that case
|
||||
if let Some(mapped) = window
|
||||
.wl_surface()
|
||||
.and_then(|surf| common.shell.element_for_surface(&surf))
|
||||
{
|
||||
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. {
|
||||
|
|
@ -1100,7 +1097,10 @@ impl UserdataExt for CosmicSurface {
|
|||
|
||||
impl State {
|
||||
pub fn schedule_window_session(&mut self, surface: &WlSurface) {
|
||||
if let Some(element) = self.common.shell.element_for_surface(surface).cloned() {
|
||||
if let Some(element) = surface
|
||||
.wl_surface()
|
||||
.and_then(|surface| self.common.shell.element_for_wl_surface(&surface).cloned())
|
||||
{
|
||||
let active = element.active_window();
|
||||
if active.wl_surface().as_ref() == Some(surface) {
|
||||
for (session, params) in active.pending_buffers() {
|
||||
|
|
|
|||
|
|
@ -7,14 +7,11 @@ use smithay::{
|
|||
find_popup_root_surface, PopupGrab, PopupKeyboardGrab, PopupKind, PopupPointerGrab,
|
||||
PopupUngrabStrategy, Window,
|
||||
},
|
||||
input::{
|
||||
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
||||
Seat,
|
||||
},
|
||||
input::{pointer::Focus, Seat},
|
||||
output::Output,
|
||||
reexports::{
|
||||
wayland_protocols::xdg::shell::server::xdg_toplevel,
|
||||
wayland_server::protocol::{wl_output::WlOutput, wl_seat::WlSeat, wl_surface::WlSurface},
|
||||
wayland_server::protocol::{wl_output::WlOutput, wl_seat::WlSeat},
|
||||
},
|
||||
utils::Serial,
|
||||
wayland::{
|
||||
|
|
@ -70,7 +67,7 @@ impl XdgShellHandler for State {
|
|||
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))
|
||||
.and_then(|root| self.common.shell.element_for_wl_surface(&root))
|
||||
{
|
||||
let target = root.clone().into();
|
||||
let ret = self
|
||||
|
|
@ -138,38 +135,7 @@ impl XdgShellHandler for State {
|
|||
|
||||
fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
|
||||
let seat = Seat::from_resource(&seat).unwrap();
|
||||
if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) {
|
||||
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 output = seat.active_output();
|
||||
let (window, _) = mapped
|
||||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
|
||||
.unwrap();
|
||||
if let Some(grab) =
|
||||
workspace.move_request(&window, &seat, &output, serial, start_data)
|
||||
{
|
||||
let handle = workspace.handle;
|
||||
self.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_leave_workspace(&window, &handle);
|
||||
self.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_leave_output(&window, &output);
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(self, grab, serial, Focus::Clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Shell::move_request(self, surface.wl_surface(), &seat, serial)
|
||||
}
|
||||
|
||||
fn resize_request(
|
||||
|
|
@ -180,24 +146,7 @@ impl XdgShellHandler for State {
|
|||
edges: xdg_toplevel::ResizeEdge,
|
||||
) {
|
||||
let seat = Seat::from_resource(&seat).unwrap();
|
||||
if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) {
|
||||
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) {
|
||||
if let Some(grab) =
|
||||
workspace.resize_request(&mapped, &seat, serial, start_data, edges)
|
||||
{
|
||||
seat.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(self, grab, serial, Focus::Clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Shell::resize_request(self, surface.wl_surface(), &seat, serial, edges.into())
|
||||
}
|
||||
|
||||
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||
|
|
@ -207,7 +156,7 @@ impl XdgShellHandler for State {
|
|||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.element_for_wl_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
|
|
@ -224,7 +173,7 @@ impl XdgShellHandler for State {
|
|||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.element_for_wl_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
|
|
@ -249,7 +198,7 @@ impl XdgShellHandler for State {
|
|||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.element_for_wl_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
|
|
@ -266,7 +215,7 @@ impl XdgShellHandler for State {
|
|||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
.element_for_surface(surface.wl_surface())
|
||||
.element_for_wl_surface(surface.wl_surface())
|
||||
.cloned()
|
||||
{
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
|
|
@ -319,36 +268,4 @@ impl XdgShellHandler for State {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_grab_preconditions(
|
||||
seat: &Seat<State>,
|
||||
surface: &WlSurface,
|
||||
serial: Serial,
|
||||
) -> Option<PointerGrabStartData<State>> {
|
||||
use smithay::reexports::wayland_server::Resource;
|
||||
|
||||
// TODO: touch resize.
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
|
||||
// Check that this surface has a click grab.
|
||||
if !pointer.has_grab(serial) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let start_data = pointer.grab_start_data().unwrap();
|
||||
|
||||
// If the focus was for a different surface, ignore the request.
|
||||
if start_data.focus.is_none()
|
||||
|| !start_data
|
||||
.focus
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.0
|
||||
.same_client_as(&surface.id())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(start_data)
|
||||
}
|
||||
|
||||
delegate_xdg_shell!(State);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use std::sync::Mutex;
|
|||
impl Shell {
|
||||
pub fn unconstrain_popup(&self, surface: &PopupSurface, positioner: &PositionerState) {
|
||||
if let Some(parent) = get_popup_toplevel(&surface) {
|
||||
if let Some(elem) = self.element_for_surface(&parent) {
|
||||
if let Some(elem) = self.element_for_wl_surface(&parent) {
|
||||
let workspace = self.space_for(elem).unwrap();
|
||||
let element_geo = workspace.element_geometry(elem).unwrap();
|
||||
let (window, offset) = elem
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue