Skip to content

Commit

Permalink
improve toplevel surface initialization.
Browse files Browse the repository at this point in the history
allows us to remove calculating the initial window size from the outputs
and instead rely on wayland directly.
  • Loading branch information
james-lawrence authored and maan2003 committed Sep 9, 2022
1 parent 4ca4098 commit 65cc1f6
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 73 deletions.
4 changes: 0 additions & 4 deletions druid-shell/src/backend/wayland/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,6 @@ impl Application {
wayland: std::rc::Rc::new(env),
});

for m in outputs::current()? {
appdata.outputs.borrow_mut().insert(m.id(), m);
}

// Collect the supported image formats.
wl_shm.quick_assign(with_cloned!(appdata; move |d1, event, d3| {
tracing::debug!("shared memory events {:?} {:?} {:?}", d1, event, d3);
Expand Down
2 changes: 1 addition & 1 deletion druid-shell/src/backend/wayland/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ pub(super) fn new(dispatcher: Dispatcher) -> Result<Environment, error::Error> {
// computation, network, ... This is good practice for all back-ends: it will improve
// responsiveness.
xdg_base.quick_assign(|xdg_base, event, ctx| {
tracing::info!(
tracing::debug!(
"global xdg_base events {:?} {:?} {:?}",
xdg_base,
event,
Expand Down
2 changes: 2 additions & 0 deletions druid-shell/src/backend/wayland/outputs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ pub struct Mode {

#[derive(Clone, Debug)]
pub struct Meta {
pub output: Option<wl_output::WlOutput>,
pub gid: u32,
pub name: String,
pub description: String,
Expand All @@ -153,6 +154,7 @@ pub struct Meta {
impl Default for Meta {
fn default() -> Self {
Self {
output: None,
gid: Default::default(),
name: Default::default(),
description: Default::default(),
Expand Down
1 change: 1 addition & 0 deletions druid-shell/src/backend/wayland/outputs/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub fn detect(
}

xdgmeta.modify(&mut m);
m.output = Some(output.detach());

if let Err(cause) = outputstx.send(outputs::Event::Located(m)) {
tracing::warn!("unable to transmit output {:?}", cause);
Expand Down
35 changes: 22 additions & 13 deletions druid-shell/src/backend/wayland/surfaces/layershell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,30 +291,38 @@ impl Outputs for Surface {
}

fn inserted(&self, o: &outputs::Meta) {
let old = String::from(
self.inner
.output
.borrow()
.preferred
.as_ref()
.map_or("", |name| name),
);

let reinitialize = *self.inner.requires_initialization.borrow();
let reinitialize = self
.inner
.output
.borrow()
.preferred
.as_ref()
.map_or("", |name| name)
== o.name
|| reinitialize;
let reinitialize = old == o.name || reinitialize;
if !reinitialize {
tracing::debug!(
"skipping reinitialization output for layershell {:?} {:?}",
"skipping reinitialization output for layershell {:?} {:?} == {:?} || {:?} -> {:?}",
o.id(),
o.name,
old,
*self.inner.requires_initialization.borrow(),
reinitialize,
);
return;
}

tracing::debug!(
"reinitializing output for layershell {:?} {:?}",
"reinitializing output for layershell {:?} {:?} == {:?} || {:?} -> {:?}",
o.id(),
o.name
o.name,
old,
*self.inner.requires_initialization.borrow(),
reinitialize,
);

let sdata = self.inner.wl_surface.borrow().inner.clone();
self.inner
.wl_surface
Expand All @@ -327,13 +335,14 @@ impl Outputs for Surface {
.unwrap()
.get_layer_surface(
&self.inner.wl_surface.borrow().inner.wl_surface.borrow(),
None,
o.output.as_ref(),
self.inner.config.layer,
self.inner.config.namespace.to_string(),
),
);

Surface::initialize(self);

replacedlayershell.destroy();
}
}
Expand Down
26 changes: 13 additions & 13 deletions druid-shell/src/backend/wayland/surfaces/toplevel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ impl Surface {
pub fn new(
c: impl Into<CompositorHandle>,
handler: Box<dyn window::WinHandler>,
initial_size: kurbo::Size,
min_size: Option<kurbo::Size>,
) -> Self {
let min_size = min_size.unwrap_or_else(|| kurbo::Size::from((1.0, 1.0)));
let compositor = CompositorHandle::new(c);
let wl_surface = surface::Surface::new(compositor.clone(), handler, kurbo::Size::ZERO);
let xdg_surface = compositor.get_xdg_surface(&wl_surface.inner.wl_surface.borrow());
Expand All @@ -47,7 +47,7 @@ impl Surface {
xdg_surface.quick_assign({
let wl_surface = wl_surface.clone();
move |xdg_surface, event, _| {
tracing::trace!("xdg_surface event configure {:?}", event);
tracing::debug!("xdg_surface event configure {:?}", event);
match event {
xdg_surface::Event::Configure { serial } => {
xdg_surface.ack_configure(serial);
Expand All @@ -61,7 +61,7 @@ impl Surface {

xdg_toplevel.quick_assign({
let wl_surface = wl_surface.clone();
let mut dim = initial_size;
let dim = min_size;
move |_xdg_toplevel, event, a3| match event {
xdg_toplevel::Event::Configure {
width,
Expand All @@ -75,11 +75,12 @@ impl Surface {
states,
a3
);
// compositor is deferring to the client for determining the size
// when values are zero.
if width != 0 && height != 0 {
dim = kurbo::Size::new(width as f64, height as f64);
}

let dim = kurbo::Size::new(
(width as f64).max(dim.width),
(height as f64).max(dim.height),
);

wl_surface.update_dimensions(dim);
}
xdg_toplevel::Event::Close => {
Expand All @@ -96,11 +97,10 @@ impl Surface {
xdg_surface,
};

if let Some(size) = min_size {
inner
.xdg_toplevel
.set_min_size(size.width as i32, size.height as i32);
}
inner
.xdg_toplevel
.set_min_size(min_size.width as i32, min_size.height as i32);
inner.xdg_toplevel.set_maximized();

let handle = Self {
inner: std::sync::Arc::new(inner),
Expand Down
66 changes: 24 additions & 42 deletions druid-shell/src/backend/wayland/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,23 +405,14 @@ impl WindowBuilder {
tracing::warn!("menus unimplemented for wayland");
}

if let WindowLevel::DropDown(parent) = self.level {
let dim = self.min_size.unwrap_or(Size::ZERO);
let dim = Size::new(dim.width.max(1.), dim.height.max(1.));
let dim = Size::new(
self.size.width.max(dim.width),
self.size.height.max(dim.height),
);

let config = surfaces::popup::Config::default()
.with_size(dim)
.with_offset(Into::into(
self.position.unwrap_or_else(|| Into::into((0., 0.))),
));
let level = self.level.clone();

tracing::debug!("popup {:?}", config);
if let WindowLevel::Modal(parent) = level {
return self.create_popup(parent);
}

return popup::create(&parent.0, &config, self.appdata, self.handler);
if let WindowLevel::DropDown(parent) = level {
return self.create_popup(parent);
}

let appdata = match self.appdata.upgrade() {
Expand All @@ -430,10 +421,8 @@ impl WindowBuilder {
};

let handler = self.handler.expect("must set a window handler");
// compute the initial window size.
let initial_size = WindowBuilder::initial_window_size(&appdata, self.size);
let surface =
surfaces::toplevel::Surface::new(appdata.clone(), handler, initial_size, self.min_size);

let surface = surfaces::toplevel::Surface::new(appdata.clone(), handler, self.min_size);

(&surface as &dyn surfaces::Decor).set_title(self.title);

Expand Down Expand Up @@ -469,30 +458,23 @@ impl WindowBuilder {
Ok(handle)
}

pub(super) fn initial_window_size(
appdata: &application::Data,
defaults: kurbo::Size,
) -> kurbo::Size {
// compute the initial window size.
let initialwidth = if defaults.width == 0.0 {
f64::INFINITY
} else {
defaults.width
};
let initialheight = if defaults.height == 0.0 {
f64::INFINITY
} else {
defaults.height
};
return appdata.outputs.borrow().iter().fold(
kurbo::Size::from((initialwidth, initialheight)),
|computed, entry| {
kurbo::Size::new(
computed.width.min(entry.1.logical.width.into()),
computed.height.min(entry.1.logical.height.into()),
)
},
fn create_popup(self, parent: window::WindowHandle) -> Result<WindowHandle, ShellError> {
let dim = self.min_size.unwrap_or(Size::ZERO);
let dim = Size::new(dim.width.max(1.), dim.height.max(1.));
let dim = Size::new(
self.size.width.max(dim.width),
self.size.height.max(dim.height),
);

let config = surfaces::popup::Config::default()
.with_size(dim)
.with_offset(Into::into(
self.position.unwrap_or_else(|| Into::into((0., 0.))),
));

tracing::debug!("popup {:?}", config);

popup::create(&parent.0, &config, self.appdata, self.handler)
}
}

Expand Down

0 comments on commit 65cc1f6

Please sign in to comment.