fix xdg-decoration + add wl-viewporter

This commit is contained in:
galister 2026-07-04 21:34:53 +09:00
parent ee82b4ab93
commit 8f09a13917
2 changed files with 39 additions and 13 deletions

View File

@ -28,14 +28,14 @@ use smithay::wayland::selection::{
wlr_data_control as selection_wlr,
};
use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState};
use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler;
use smithay::wayland::shell::xdg::decoration::{XdgDecorationHandler, XdgDecorationState};
use smithay::wayland::shm::{ShmHandler, ShmState, with_buffer_contents};
use smithay::wayland::single_pixel_buffer::get_single_pixel_buffer;
use smithay::{
delegate_compositor, delegate_data_control, delegate_data_device, delegate_dmabuf,
delegate_ext_data_control, delegate_kde_decoration, delegate_output,
delegate_primary_selection, delegate_seat, delegate_shm, delegate_single_pixel_buffer,
delegate_xdg_decoration, delegate_xdg_shell,
delegate_viewporter, delegate_xdg_decoration, delegate_xdg_shell,
};
use std::collections::{HashMap, HashSet};
use std::fs::File;
@ -77,6 +77,7 @@ pub struct Application {
pub primary_selection_state: PrimarySelectionState,
pub ext_data_control_state: selection_ext::DataControlState,
pub wlr_data_control_state: selection_wlr::DataControlState,
pub xdg_decoration_state: XdgDecorationState,
pub kde_decoration_state: KdeDecorationState,
pub wayvr_tasks: SyncEventQueue<WayVRTask>,
pub popup_manager: PopupManager,
@ -163,10 +164,6 @@ impl Application {
pub fn take_redraw_request(&mut self, surface_id: &ObjectId) -> bool {
self.redraw_requests.remove(surface_id)
}
pub fn has_redraw_request(&self, surface_id: &ObjectId) -> bool {
self.redraw_requests.contains(surface_id)
}
}
impl compositor::CompositorHandler for Application {
@ -604,6 +601,7 @@ impl KdeDecorationHandler for Application {
delegate_dmabuf!(Application);
delegate_xdg_shell!(Application);
delegate_compositor!(Application);
delegate_viewporter!(Application);
delegate_shm!(Application);
delegate_seat!(Application);
delegate_data_device!(Application);

View File

@ -5,7 +5,8 @@ use smithay::{
utils::{Logical, Point},
wayland::{
compositor::{
SubsurfaceCachedState, TraversalAction, with_states, with_surface_tree_upward,
SUBSURFACE_ROLE, SubsurfaceCachedState, SurfaceAttributes, TraversalAction,
with_states, with_surface_tree_upward,
},
shell::xdg::XdgPopupSurfaceData,
},
@ -367,11 +368,11 @@ impl WvrWindowBackend {
return self.panel_hit_from_hit(hit).map(WvrHitTarget::Panel);
}
let hit_surface = self.surfaces.iter().rev().find(|s| {
let local = client_pos - s.pos;
local.x >= 0.0 && local.y >= 0.0 && local.x < s.size.x && local.y < s.size.y
});
let hit_surface = self
.surfaces
.iter()
.rev()
.find(|s| surface_accepts_input(s, client_pos));
if let Some(surface) = hit_surface {
return Some(WvrHitTarget::Surface {
@ -939,7 +940,7 @@ fn rendered_surfaces_dirty(old: &[RenderedSurface], new: &[RenderedSurface]) ->
}
fn surface_location(states: &smithay::wayland::compositor::SurfaceData) -> Point<i32, Logical> {
if states.role == Some("wl_subsurface") {
if states.role == Some(SUBSURFACE_ROLE) {
let mut guard = states.cached_state.get::<SubsurfaceCachedState>();
guard.current().location
} else {
@ -949,6 +950,7 @@ fn surface_location(states: &smithay::wayland::compositor::SurfaceData) -> Point
fn collect_rendered_surface_tree(root: &WlSurface) -> Vec<RenderedSurface> {
let mut out = Vec::new();
let root_id = root.id();
with_surface_tree_upward(
root,
@ -960,6 +962,10 @@ fn collect_rendered_surface_tree(root: &WlSurface) -> Vec<RenderedSurface> {
TraversalAction::DoChildren(pos)
},
|surface, states, parent_pos| {
if surface.id() == root_id {
return;
}
let pos = *parent_pos + surface_location(states);
if let Some(surf) = SurfaceBufWithImage::get_from_surface(states) {
@ -981,3 +987,25 @@ fn collect_rendered_surface_tree(root: &WlSurface) -> Vec<RenderedSurface> {
out
}
fn surface_accepts_input(surface: &RenderedSurface, global_pos: Vec2) -> bool {
let local = global_pos - surface.pos;
if local.x < 0.0 || local.y < 0.0 || local.x >= surface.size.x || local.y >= surface.size.y {
return false;
}
with_states(&surface.surface, |states| {
let mut guard = states.cached_state.get::<SurfaceAttributes>();
let attrs = guard.current();
match attrs.input_region.as_ref() {
None => true,
Some(region) => {
let point =
Point::<i32, Logical>::from((local.x.floor() as i32, local.y.floor() as i32));
region.contains(point)
}
}
})
}