update
This commit is contained in:
+5
-1
@@ -33,7 +33,7 @@ use wayland_client::{
|
||||
Connection, Dispatch, Proxy, QueueHandle, delegate_noop,
|
||||
protocol::{
|
||||
wl_buffer, wl_compositor, wl_keyboard, wl_pointer, wl_registry, wl_seat, wl_shm,
|
||||
wl_shm_pool, wl_surface,
|
||||
wl_shm_pool, wl_subcompositor, wl_subsurface, wl_surface,
|
||||
},
|
||||
};
|
||||
use wayland_protocols::wp::cursor_shape::v1::client::{
|
||||
@@ -111,6 +111,7 @@ pub struct Globals {
|
||||
pub wm_base: xdg_wm_base::XdgWmBase,
|
||||
pub shm: wl_shm::WlShm,
|
||||
pub seat: wl_seat::WlSeat,
|
||||
pub subcompositor: Option<wl_subcompositor::WlSubcompositor>,
|
||||
pub viewporter: Option<wp_viewporter::WpViewporter>,
|
||||
pub fractional_scale_manager:
|
||||
Option<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1>,
|
||||
@@ -149,6 +150,7 @@ impl Globals {
|
||||
shm: globals.bind(&qh, 1..=1, ()).unwrap(),
|
||||
seat,
|
||||
wm_base: globals.bind(&qh, 2..=5, ()).unwrap(),
|
||||
subcompositor: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
viewporter: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
fractional_scale_manager: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
decoration_manager: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
@@ -943,6 +945,8 @@ delegate_noop!(WaylandClientStatePtr: ignore wl_shm::WlShm);
|
||||
delegate_noop!(WaylandClientStatePtr: ignore wl_shm_pool::WlShmPool);
|
||||
delegate_noop!(WaylandClientStatePtr: ignore wl_buffer::WlBuffer);
|
||||
delegate_noop!(WaylandClientStatePtr: ignore wl_region::WlRegion);
|
||||
delegate_noop!(WaylandClientStatePtr: wl_subcompositor::WlSubcompositor);
|
||||
delegate_noop!(WaylandClientStatePtr: wl_subsurface::WlSubsurface);
|
||||
delegate_noop!(WaylandClientStatePtr: ignore wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1);
|
||||
delegate_noop!(WaylandClientStatePtr: ignore zxdg_decoration_manager_v1::ZxdgDecorationManagerV1);
|
||||
delegate_noop!(WaylandClientStatePtr: ignore org_kde_kwin_blur_manager::OrgKdeKwinBlurManager);
|
||||
|
||||
+71
-1
@@ -13,7 +13,10 @@ use futures::channel::oneshot::Receiver;
|
||||
use raw_window_handle as rwh;
|
||||
use wayland_backend::client::ObjectId;
|
||||
use wayland_client::WEnum;
|
||||
use wayland_client::{Proxy, protocol::wl_surface};
|
||||
use wayland_client::{
|
||||
Proxy,
|
||||
protocol::{wl_subsurface, wl_surface},
|
||||
};
|
||||
use wayland_protocols::wp::viewporter::client::wp_viewport;
|
||||
use wayland_protocols::xdg::decoration::zv1::client::zxdg_toplevel_decoration_v1;
|
||||
use wayland_protocols::xdg::shell::client::xdg_surface;
|
||||
@@ -92,6 +95,7 @@ pub struct WaylandWindowState {
|
||||
blur: Option<org_kde_kwin_blur::OrgKdeKwinBlur>,
|
||||
toplevel: xdg_toplevel::XdgToplevel,
|
||||
viewport: Option<wp_viewport::WpViewport>,
|
||||
native_surfaces: HashMap<usize, WaylandNativeSurface>,
|
||||
outputs: HashMap<ObjectId, Output>,
|
||||
display: Option<(ObjectId, Output)>,
|
||||
globals: Globals,
|
||||
@@ -166,6 +170,7 @@ impl WaylandWindowState {
|
||||
blur: None,
|
||||
toplevel,
|
||||
viewport,
|
||||
native_surfaces: HashMap::default(),
|
||||
globals,
|
||||
outputs: HashMap::default(),
|
||||
display: None,
|
||||
@@ -222,6 +227,22 @@ impl WaylandWindowState {
|
||||
}
|
||||
}
|
||||
|
||||
struct WaylandNativeSurface {
|
||||
surface: wl_surface::WlSurface,
|
||||
subsurface: wl_subsurface::WlSubsurface,
|
||||
viewport: Option<wp_viewport::WpViewport>,
|
||||
}
|
||||
|
||||
impl WaylandNativeSurface {
|
||||
fn destroy(self) {
|
||||
if let Some(viewport) = self.viewport {
|
||||
viewport.destroy();
|
||||
}
|
||||
self.subsurface.destroy();
|
||||
self.surface.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct WaylandWindow(pub WaylandWindowStatePtr);
|
||||
pub enum ImeInput {
|
||||
InsertText(String),
|
||||
@@ -247,6 +268,9 @@ impl Drop for WaylandWindow {
|
||||
if let Some(viewport) = &state.viewport {
|
||||
viewport.destroy();
|
||||
}
|
||||
for (_, native_surface) in state.native_surfaces.drain() {
|
||||
native_surface.destroy();
|
||||
}
|
||||
state.xdg_surface.destroy();
|
||||
state.surface.destroy();
|
||||
|
||||
@@ -1032,6 +1056,52 @@ impl PlatformWindow for WaylandWindow {
|
||||
state.renderer.sprite_atlas().clone()
|
||||
}
|
||||
|
||||
fn create_native_surface(&self) -> Option<crate::NativeSurfaceHandle> {
|
||||
let mut state = self.borrow_mut();
|
||||
let subcompositor = state.globals.subcompositor.as_ref()?;
|
||||
let surface = state.globals.compositor.create_surface(&state.globals.qh, ());
|
||||
let subsurface =
|
||||
subcompositor.get_subsurface(&surface, &state.surface, &state.globals.qh, ());
|
||||
subsurface.set_desync();
|
||||
let viewport = state
|
||||
.globals
|
||||
.viewporter
|
||||
.as_ref()
|
||||
.map(|viewporter| viewporter.get_viewport(&surface, &state.globals.qh, ()));
|
||||
let display = surface.backend().upgrade()?.display_ptr().cast::<c_void>() as usize;
|
||||
let surface_id = surface.id().as_ptr().cast::<c_void>() as usize;
|
||||
surface.commit();
|
||||
state.native_surfaces.insert(
|
||||
surface_id,
|
||||
WaylandNativeSurface {
|
||||
surface,
|
||||
subsurface,
|
||||
viewport,
|
||||
},
|
||||
);
|
||||
Some(crate::NativeSurfaceHandle::from_wayland_surface(
|
||||
surface_id, display,
|
||||
))
|
||||
}
|
||||
|
||||
fn sync_native_surface(&self, surface: &crate::NativeSurfaceHandle, bounds: Bounds<Pixels>) {
|
||||
let state = self.borrow();
|
||||
let bounds = bounds.to_device_pixels(state.scale);
|
||||
if let Some(native_surface) = state.native_surfaces.get(&surface.identity()) {
|
||||
native_surface
|
||||
.subsurface
|
||||
.set_position(bounds.origin.x.0, bounds.origin.y.0);
|
||||
if let Some(viewport) = native_surface.viewport.as_ref() {
|
||||
viewport.set_destination(
|
||||
bounds.size.width.0.max(1),
|
||||
bounds.size.height.0.max(1),
|
||||
);
|
||||
}
|
||||
native_surface.surface.commit();
|
||||
state.surface.commit();
|
||||
}
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, position: Point<Pixels>) {
|
||||
let state = self.borrow();
|
||||
let serial = state.client.get_serial(SerialKind::MousePress);
|
||||
|
||||
+64
-4
@@ -4,10 +4,11 @@ use x11rb::connection::RequestConnection;
|
||||
use crate::platform::blade::{BladeContext, BladeRenderer, BladeSurfaceConfig};
|
||||
use crate::{
|
||||
AnyWindowHandle, Bounds, Decorations, DevicePixels, ForegroundExecutor, GpuSpecs, Modifiers,
|
||||
Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow,
|
||||
Point, PromptButton, PromptLevel, RequestFrameOptions, ResizeEdge, ScaledPixels, Scene, Size,
|
||||
Tiling, WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowControlArea,
|
||||
WindowDecorations, WindowKind, WindowParams, X11ClientStatePtr, px, size,
|
||||
NativeSurfaceHandle, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput,
|
||||
PlatformInputHandler, PlatformWindow, Point, PromptButton, PromptLevel, RequestFrameOptions,
|
||||
ResizeEdge, ScaledPixels, Scene, Size, Tiling, WindowAppearance, WindowBackgroundAppearance,
|
||||
WindowBounds, WindowControlArea, WindowDecorations, WindowKind, WindowParams,
|
||||
X11ClientStatePtr, px, size,
|
||||
};
|
||||
|
||||
use blade_graphics as gpu;
|
||||
@@ -253,6 +254,8 @@ pub struct X11WindowState {
|
||||
executor: ForegroundExecutor,
|
||||
atoms: XcbAtoms,
|
||||
x_root_window: xproto::Window,
|
||||
x_screen_id: usize,
|
||||
x_visual_id: u32,
|
||||
pub(crate) counter_id: sync::Counter,
|
||||
pub(crate) last_sync_counter: Option<sync::Int64>,
|
||||
bounds: Bounds<Pixels>,
|
||||
@@ -671,6 +674,8 @@ impl X11WindowState {
|
||||
executor,
|
||||
display,
|
||||
x_root_window: visual_set.root,
|
||||
x_screen_id: x_screen_index,
|
||||
x_visual_id: visual.id,
|
||||
bounds: bounds.to_pixels(scale_factor),
|
||||
scale_factor,
|
||||
renderer,
|
||||
@@ -1480,6 +1485,61 @@ impl PlatformWindow for X11Window {
|
||||
inner.renderer.sprite_atlas().clone()
|
||||
}
|
||||
|
||||
fn create_native_surface(&self) -> Option<NativeSurfaceHandle> {
|
||||
let state = self.0.state.borrow();
|
||||
let window_id = self.0.xcb.generate_id().log_err()?;
|
||||
let aux = xproto::CreateWindowAux::new().event_mask(xproto::EventMask::NO_EVENT);
|
||||
check_reply(
|
||||
|| "X11 CreateWindow failed for native surface.",
|
||||
self.0.xcb.create_window(
|
||||
0,
|
||||
window_id,
|
||||
self.0.x_window,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
xproto::WindowClass::INPUT_OUTPUT,
|
||||
0,
|
||||
&aux,
|
||||
),
|
||||
)
|
||||
.log_err()?;
|
||||
check_reply(
|
||||
|| "X11 MapWindow failed for native surface.",
|
||||
self.0.xcb.map_window(window_id),
|
||||
)
|
||||
.log_err()?;
|
||||
xcb_flush(&self.0.xcb);
|
||||
Some(NativeSurfaceHandle::from_xcb_window(
|
||||
as_raw_xcb_connection::AsRawXcbConnection::as_raw_xcb_connection(&*self.0.xcb)
|
||||
as usize,
|
||||
state.x_screen_id as i32,
|
||||
window_id,
|
||||
state.x_visual_id,
|
||||
))
|
||||
}
|
||||
|
||||
fn sync_native_surface(&self, surface: &NativeSurfaceHandle, bounds: Bounds<Pixels>) {
|
||||
let state = self.0.state.borrow();
|
||||
let bounds = bounds.to_device_pixels(state.scale_factor);
|
||||
drop(state);
|
||||
check_reply(
|
||||
|| "X11 ConfigureWindow failed for native surface.",
|
||||
self.0.xcb.configure_window(
|
||||
surface.xcb_window_id(),
|
||||
&xproto::ConfigureWindowAux::new()
|
||||
.x(bounds.origin.x.0)
|
||||
.y(bounds.origin.y.0)
|
||||
.width(bounds.size.width.0.max(1) as u32)
|
||||
.height(bounds.size.height.0.max(1) as u32),
|
||||
),
|
||||
)
|
||||
.log_err();
|
||||
xcb_flush(&self.0.xcb);
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, position: Point<Pixels>) {
|
||||
let state = self.0.state.borrow();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user