Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions src/native/linux_wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,33 @@ impl WaylandPayload {
} else {
(self.client.wl_display_cancel_read)(self.display);
}
let errno = (self.client.wl_display_get_error)(self.display);
// A non-zero errno means the compositor decided that we need to die.
// Nothing more we can do at this point :(
// If we want the detailed error message, we need to run with `WAYLAND_DEBUG=client`, since
// the message string is not accessible to us.
match errno {
0 => (),
EPROTO => {
let mut interface: *const wl_interface = std::ptr::null();
let mut id = 0;
let code = (self.client.wl_display_get_protocol_error)(
self.display,
&mut interface,
&mut id,
);
let name = core::ffi::CStr::from_ptr((*interface).name)
.to_str()
.unwrap();
panic!(
"Wayland protocol error at {}#{} with code {}",
name, id, code
)
}
_ => {
panic!("Wayland display error with code {}", errno)
}
}
}
unsafe fn init_data_device(&mut self) {
self.data_device = wl_request_constructor!(
Expand Down Expand Up @@ -663,9 +690,11 @@ unsafe extern "C" fn pointer_handle_enter(
) {
let display: &mut WaylandPayload = &mut *(data as *mut _);
display.focused_window = surface;
display
.pointer_context
.handle_enter(&mut display.client, serial);
if surface == display.surface {
display
.pointer_context
.handle_enter(&mut display.client, serial);
}
}

unsafe extern "C" fn pointer_handle_leave(
Expand Down Expand Up @@ -758,23 +787,16 @@ unsafe extern "C" fn relative_pointer_handle_relative_motion(
}

unsafe extern "C" fn output_handle_scale(
data: *mut std::ffi::c_void,
_data: *mut std::ffi::c_void,
_output: *mut wl_output,
factor: core::ffi::c_int,
) {
let display: &mut WaylandPayload = &mut *(data as *mut _);
let mut d = crate::native_display().try_lock().unwrap();
if d.high_dpi {
let dpi_scale = d.dpi_scale as i32;
d.screen_width = d.screen_width / dpi_scale * factor;
d.screen_height = d.screen_height / dpi_scale * factor;
d.dpi_scale = factor as _;
wl_request!(
display.client,
display.surface,
WL_SURFACE_SET_BUFFER_SCALE,
factor
);
}
}

Expand Down Expand Up @@ -1097,7 +1119,7 @@ where
let clipboard = Box::new(clipboard::WaylandClipboard::new(&mut display as *mut _));
crate::set_display(NativeDisplayData {
high_dpi: conf.high_dpi,
dpi_scale: 1.,
dpi_scale: 1., // At this point dpi_scale is not known to us
blocking_event_loop: conf.platform.blocking_event_loop,
..NativeDisplayData::new(conf.window_width, conf.window_height, tx, clipboard)
});
Expand All @@ -1118,12 +1140,19 @@ where
.unwrap();

{
// At this point we have been told the dpi_scale
let d = crate::native_display().try_lock().unwrap();
display.egl_window = (display.egl.wl_egl_window_create)(
display.surface as _,
d.screen_width,
d.screen_height,
);
wl_request!(
display.client,
display.surface,
WL_SURFACE_SET_BUFFER_SCALE,
d.dpi_scale as i32
);
}

let egl_surface = (libegl.eglCreateWindowSurface)(
Expand Down
10 changes: 10 additions & 0 deletions src/native/linux_wayland/decorations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,16 @@ unsafe extern "C" fn handle_configure(data: *mut std::ffi::c_void, width: i32, h
fallback.resize(&mut payload.client, width, height);
}
(payload.egl.wl_egl_window_resize)(payload.egl_window, window_width, window_height, 0, 0);
// We need to ensure that the buffer has been correctly resized before setting the
// dpi_scale, since Wayland would rather crash than letting you have a width that's an
// odd number on a display with 2x dpi...
(payload.client.wl_display_dispatch_pending)(payload.display);
wl_request!(
payload.client,
payload.surface,
WL_SURFACE_SET_BUFFER_SCALE,
dpi_scale
);
// The compositor can send multiple resizing configure during a single frame, and we
// probably don't want to fire the resize event for every one of them
// So if we still have a Resize event in the queue, instead of pushing a new one, we batch
Expand Down
7 changes: 7 additions & 0 deletions src/native/linux_wayland/libwayland_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ pub const WL_SUBSURFACE_PLACE_BELOW_SINCE_VERSION: u32 = 1;
pub const WL_SUBSURFACE_SET_SYNC_SINCE_VERSION: u32 = 1;
pub const WL_SUBSURFACE_SET_DESYNC_SINCE_VERSION: u32 = 1;

pub const ENOMEM: c_int = 12;
pub const EFAULT: c_int = 14;
pub const EINVAL: c_int = 22;
pub const EPROTO: c_int = 71;

pub type wl_shm_format = ::core::ffi::c_uint;

pub const wl_shm_format_WL_SHM_FORMAT_ARGB8888: wl_shm_format = 0;
Expand Down Expand Up @@ -608,6 +613,8 @@ crate::declare_module!(
pub fn wl_display_dispatch_pending(*mut wl_display) -> c_int,
pub fn wl_display_dispatch_queue(*mut wl_display, *mut wl_event_queue) -> c_int,
pub fn wl_display_dispatch_queue_pending(*mut wl_display, *mut wl_event_queue) -> c_int,
pub fn wl_display_get_error(*mut wl_display) -> c_int,
pub fn wl_display_get_protocol_error(*mut wl_display, *mut *const wl_interface, *mut c_uint) -> c_uint,
pub fn wl_proxy_set_queue(*mut wl_proxy, *mut wl_event_queue),
pub fn wl_proxy_get_queue(*mut wl_proxy) -> *mut wl_event_queue,
pub fn wl_proxy_add_listener(*mut wl_proxy, *mut Option<unsafe extern "C" fn()>, *mut c_void) -> c_int,
Expand Down
Loading