1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 13:21:38 +03:00

wayland: fix initial window decoration, toggle full screen

This fixes a longstanding issue under mutter where client side
decorations are in use.  The decorations were being drawn too
early in the initialization of the window which could leave them
off-screen and weird.  This was masked by a couple of mutter
related bugs with client side decorations.

With these changes I now get sane decorations under mutter,
and the toggle fullscreen action is now enabled as well!

closes: #224
This commit is contained in:
Wez Furlong 2021-02-13 10:58:50 -08:00
parent 894d056947
commit f697de82fc
2 changed files with 54 additions and 12 deletions

View File

@ -16,6 +16,7 @@ brief notes about them may accumulate here.
* Updated bundled JetBrainsMono font to version 2.225
* Fixed an issue where the window would be redrawn on mouse move. This was most noticeable as a laggy mouse pointer when moving the mouse across a window running on the nouveau display driver on X11 and Wayland systems
* Wayland: the raw key modifiers are now correctly propagated so that they activate when used with key assignments using the `key = "raw:123"` binding syntax.
* Wayland: fixed window decoration and full screen handling [#224](https://github.com/wez/wezterm/issues/224)
### 20210203-095643-70a364eb

View File

@ -22,7 +22,7 @@ use std::sync::{Arc, Mutex};
use toolkit::get_surface_scale_factor;
use toolkit::reexports::client::protocol::wl_data_source::Event as DataSourceEvent;
use toolkit::reexports::client::protocol::wl_surface::WlSurface;
use toolkit::window::{ButtonColorSpec, ColorSpec, ConceptConfig, ConceptFrame, Event};
use toolkit::window::{ButtonColorSpec, ColorSpec, ConceptConfig, ConceptFrame, Event, State};
use wayland_client::protocol::wl_data_device_manager::WlDataDeviceManager;
use wayland_egl::{is_available as egl_is_available, WlEglSurface};
use wezterm_input_types::*;
@ -85,6 +85,7 @@ pub struct WaylandWindowInner {
window: Option<toolkit::window::Window<ConceptFrame>>,
dimensions: Dimensions,
need_paint: bool,
full_screen: bool,
last_mouse_coords: Point,
mouse_buttons: MouseButtons,
modifiers: Modifiers,
@ -100,10 +101,11 @@ pub struct WaylandWindowInner {
#[derive(Default, Clone, Debug)]
struct PendingEvent {
close: bool,
start: bool,
had_configure_event: bool,
refresh_decorations: bool,
configure: Option<(u32, u32)>,
dpi: Option<i32>,
full_screen: Option<bool>,
}
impl PendingEvent {
@ -125,16 +127,29 @@ impl PendingEvent {
false
}
}
Event::Configure { new_size, .. } => {
let changed;
Event::Configure { new_size, states } => {
let mut changed;
self.had_configure_event = true;
if let Some(new_size) = new_size {
changed = self.configure.is_none();
self.configure.replace(new_size);
} else {
changed = !self.refresh_decorations;
self.refresh_decorations = true;
changed = true;
}
let full_screen = states.contains(&State::Fullscreen);
log::debug!(
"Config: self.full_screen={:?}, states:{:?} {:?}",
self.full_screen,
full_screen,
states
);
match (self.full_screen, full_screen) {
(None, false) => {}
_ => {
self.full_screen.replace(full_screen);
changed = true;
}
}
self.start = true;
changed
}
}
@ -218,6 +233,7 @@ impl WaylandWindow {
window.set_resizable(true);
window.set_title(name.to_string());
window.set_frame_config(frame_config());
window.set_min_size(Some((32, 32)));
// window.new_seat(&conn.seat);
conn.keyboard.add_window(window_id, &surface);
@ -235,6 +251,7 @@ impl WaylandWindow {
window: Some(window),
dimensions,
need_paint: true,
full_screen: false,
last_mouse_coords: Point::new(0, 0),
mouse_buttons: MouseButtons::NONE,
modifiers: Modifiers::NONE,
@ -439,6 +456,15 @@ impl WaylandWindowInner {
self.window.take();
}
if let Some(full_screen) = pending.full_screen.take() {
log::debug!(
"dispatch_pending_event self.full_screen={} pending:{}",
self.full_screen,
full_screen
);
self.full_screen = full_screen;
}
if pending.configure.is_none() && pending.dpi.is_some() {
// Synthesize a pending configure event for the dpi change
pending.configure.replace((
@ -489,7 +515,7 @@ impl WaylandWindowInner {
if pending.refresh_decorations && self.window.is_some() {
self.refresh_frame();
}
if pending.start && self.window.is_some() && self.wegl_surface.is_none() {
if pending.had_configure_event && self.window.is_some() && self.wegl_surface.is_none() {
self.enable_opengl().unwrap();
}
}
@ -497,7 +523,7 @@ impl WaylandWindowInner {
fn refresh_frame(&mut self) {
if let Some(window) = self.window.as_mut() {
window.refresh();
self.surface.commit();
window.surface().commit();
}
}
@ -591,6 +617,13 @@ impl WindowOps for WaylandWindow {
})
}
fn toggle_fullscreen(&self) -> Future<()> {
WaylandConnection::with_window_inner(self.0, |inner| {
inner.toggle_fullscreen();
Ok(())
})
}
fn show(&self) -> Future<()> {
WaylandConnection::with_window_inner(self.0, |inner| {
inner.show();
@ -773,6 +806,16 @@ impl WindowOpsMut for WaylandWindowInner {
}
}
fn toggle_fullscreen(&mut self) {
if let Some(window) = self.window.as_ref() {
if self.full_screen {
window.unset_fullscreen();
} else {
window.set_fullscreen(None);
}
}
}
fn show(&mut self) {
if self.window.is_none() {
return;
@ -787,8 +830,6 @@ impl WindowOpsMut for WaylandWindowInner {
.needs_configure()
{
self.do_paint().unwrap();
} else {
self.refresh_frame();
}
}
@ -834,7 +875,7 @@ impl WindowOpsMut for WaylandWindowInner {
window.refresh();
// In addition, resize doesn't take effect until
// the suface is commited
self.surface.commit();
window.surface().commit();
}
}