examples: introduce window_map
This commit is contained in:
parent
e3cb52d06b
commit
e6eb03c184
|
@ -17,7 +17,7 @@ use drm::control::{Device as ControlDevice, ResourceInfo};
|
||||||
use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
||||||
use drm::control::encoder::Info as EncoderInfo;
|
use drm::control::encoder::Info as EncoderInfo;
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
use helpers::{shell_implementation, surface_implementation, GliumDrawer, Roles, SurfaceData};
|
use helpers::{init_shell, GliumDrawer, MyWindowMap, Roles, SurfaceData};
|
||||||
use slog::{Drain, Logger};
|
use slog::{Drain, Logger};
|
||||||
use smithay::backend::drm::{drm_device_bind, DrmBackend, DrmDevice, DrmHandler};
|
use smithay::backend::drm::{drm_device_bind, DrmBackend, DrmDevice, DrmHandler};
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
|
@ -25,8 +25,10 @@ use smithay::compositor::{compositor_init, CompositorToken, SubsurfaceRole, Trav
|
||||||
use smithay::compositor::roles::Role;
|
use smithay::compositor::roles::Role;
|
||||||
use smithay::shell::{shell_init, ShellState};
|
use smithay::shell::{shell_init, ShellState};
|
||||||
use smithay::shm::init_shm_global;
|
use smithay::shm::init_shm_global;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use wayland_server::{EventLoopHandle, StateToken};
|
use wayland_server::{EventLoopHandle, StateToken};
|
||||||
|
|
||||||
|
@ -89,16 +91,7 @@ fn main() {
|
||||||
|
|
||||||
init_shm_global(&mut event_loop, vec![], log.clone());
|
init_shm_global(&mut event_loop, vec![], log.clone());
|
||||||
|
|
||||||
let (compositor_token, _, _) =
|
let (compositor_token, shell_state_token, window_map) = init_shell(&mut event_loop, log.clone());
|
||||||
compositor_init(&mut event_loop, surface_implementation(), (), log.clone());
|
|
||||||
|
|
||||||
let (shell_state_token, _, _) = shell_init(
|
|
||||||
&mut event_loop,
|
|
||||||
compositor_token,
|
|
||||||
shell_implementation(),
|
|
||||||
compositor_token,
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize glium
|
* Initialize glium
|
||||||
|
@ -125,16 +118,23 @@ fn main() {
|
||||||
DrmHandlerImpl {
|
DrmHandlerImpl {
|
||||||
shell_state_token,
|
shell_state_token,
|
||||||
compositor_token,
|
compositor_token,
|
||||||
|
window_map: window_map.clone(),
|
||||||
logger: log,
|
logger: log,
|
||||||
},
|
},
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
event_loop.run().unwrap();
|
loop {
|
||||||
|
event_loop.dispatch(Some(16)).unwrap();
|
||||||
|
display.flush_clients();
|
||||||
|
|
||||||
|
window_map.borrow_mut().refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmHandlerImpl {
|
pub struct DrmHandlerImpl {
|
||||||
shell_state_token: StateToken<ShellState<SurfaceData, Roles, (), ()>>,
|
shell_state_token: StateToken<ShellState<SurfaceData, Roles, (), ()>>,
|
||||||
compositor_token: CompositorToken<SurfaceData, Roles, ()>,
|
compositor_token: CompositorToken<SurfaceData, Roles, ()>,
|
||||||
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,13 +148,13 @@ impl DrmHandler<GliumDrawer<DrmBackend>> for DrmHandlerImpl {
|
||||||
// redraw the frame, in a simple but inneficient way
|
// redraw the frame, in a simple but inneficient way
|
||||||
{
|
{
|
||||||
let screen_dimensions = drawer.get_framebuffer_dimensions();
|
let screen_dimensions = drawer.get_framebuffer_dimensions();
|
||||||
for toplevel_surface in state.get(&self.shell_state_token).toplevel_surfaces() {
|
self.window_map
|
||||||
|
.borrow()
|
||||||
|
.with_windows_from_bottom_to_top(|toplevel_surface, initial_place| {
|
||||||
if let Some(wl_surface) = toplevel_surface.get_surface() {
|
if let Some(wl_surface) = toplevel_surface.get_surface() {
|
||||||
// this surface is a root of a subsurface tree that needs to be drawn
|
// this surface is a root of a subsurface tree that needs to be drawn
|
||||||
let initial_place = self.compositor_token
|
|
||||||
.with_surface_data(wl_surface, |data| data.user_data.location.unwrap_or((0, 0)));
|
|
||||||
self.compositor_token
|
self.compositor_token
|
||||||
.with_surface_tree(
|
.with_surface_tree_upward(
|
||||||
wl_surface,
|
wl_surface,
|
||||||
initial_place,
|
initial_place,
|
||||||
|_surface, attributes, role, &(mut x, mut y)| {
|
|_surface, attributes, role, &(mut x, mut y)| {
|
||||||
|
@ -164,7 +164,13 @@ impl DrmHandler<GliumDrawer<DrmBackend>> for DrmHandlerImpl {
|
||||||
x += subdata.x;
|
x += subdata.x;
|
||||||
y += subdata.y;
|
y += subdata.y;
|
||||||
}
|
}
|
||||||
drawer.render(&mut frame, contents, (w, h), (x, y), screen_dimensions);
|
drawer.render(
|
||||||
|
&mut frame,
|
||||||
|
contents,
|
||||||
|
(w, h),
|
||||||
|
(x, y),
|
||||||
|
screen_dimensions,
|
||||||
|
);
|
||||||
TraversalAction::DoChildren((x, y))
|
TraversalAction::DoChildren((x, y))
|
||||||
} else {
|
} else {
|
||||||
// we are not display, so our children are neither
|
// we are not display, so our children are neither
|
||||||
|
@ -174,7 +180,7 @@ impl DrmHandler<GliumDrawer<DrmBackend>> for DrmHandlerImpl {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
frame.finish().unwrap();
|
frame.finish().unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
|
use super::WindowMap;
|
||||||
use rand;
|
use rand;
|
||||||
use smithay::compositor::{CompositorToken, SurfaceUserImplementation};
|
use smithay::compositor::{compositor_init, CompositorToken, SurfaceAttributes, SurfaceUserImplementation};
|
||||||
use smithay::shell::{PopupConfigure, ShellSurfaceRole, ShellSurfaceUserImplementation, ToplevelConfigure};
|
use smithay::shell::{shell_init, PopupConfigure, ShellState, ShellSurfaceRole,
|
||||||
|
ShellSurfaceUserImplementation, ToplevelConfigure};
|
||||||
use smithay::shm::with_buffer_contents;
|
use smithay::shm::with_buffer_contents;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use wayland_server::{EventLoop, StateToken};
|
||||||
|
|
||||||
define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] );
|
define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] );
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct SurfaceData {
|
pub struct SurfaceData {
|
||||||
pub buffer: Option<(Vec<u8>, (u32, u32))>,
|
pub buffer: Option<(Vec<u8>, (u32, u32))>,
|
||||||
pub location: Option<(i32, i32)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn surface_implementation() -> SurfaceUserImplementation<SurfaceData, Roles, ()> {
|
pub fn surface_implementation() -> SurfaceUserImplementation<SurfaceData, Roles, ()> {
|
||||||
|
@ -48,24 +52,26 @@ pub fn surface_implementation() -> SurfaceUserImplementation<SurfaceData, Roles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shell_implementation(
|
pub struct ShellIData<F> {
|
||||||
)
|
pub token: CompositorToken<SurfaceData, Roles, ()>,
|
||||||
-> ShellSurfaceUserImplementation<SurfaceData, Roles, (), CompositorToken<SurfaceData, Roles, ()>, ()>
|
pub window_map: Rc<RefCell<super::WindowMap<SurfaceData, Roles, (), (), F>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shell_implementation<F>() -> ShellSurfaceUserImplementation<SurfaceData, Roles, (), ShellIData<F>, ()>
|
||||||
|
where
|
||||||
|
F: Fn(&SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)>,
|
||||||
{
|
{
|
||||||
ShellSurfaceUserImplementation {
|
ShellSurfaceUserImplementation {
|
||||||
new_client: |_, _, _| {},
|
new_client: |_, _, _| {},
|
||||||
client_pong: |_, _, _| {},
|
client_pong: |_, _, _| {},
|
||||||
new_toplevel: |_, token, toplevel| {
|
new_toplevel: |_, idata, toplevel| {
|
||||||
let wl_surface = toplevel.get_surface().unwrap();
|
|
||||||
token.with_surface_data(wl_surface, |data| {
|
|
||||||
// place the window at a random location in the [0;300]x[0;300] square
|
// place the window at a random location in the [0;300]x[0;300] square
|
||||||
use rand::distributions::{IndependentSample, Range};
|
use rand::distributions::{IndependentSample, Range};
|
||||||
let range = Range::new(0, 300);
|
let range = Range::new(0, 300);
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let x = range.ind_sample(&mut rng);
|
let x = range.ind_sample(&mut rng);
|
||||||
let y = range.ind_sample(&mut rng);
|
let y = range.ind_sample(&mut rng);
|
||||||
data.user_data.location = Some((x, y))
|
idata.window_map.borrow_mut().insert(toplevel, (x, y));
|
||||||
});
|
|
||||||
ToplevelConfigure {
|
ToplevelConfigure {
|
||||||
size: None,
|
size: None,
|
||||||
states: vec![],
|
states: vec![],
|
||||||
|
@ -92,3 +98,47 @@ pub fn shell_implementation(
|
||||||
show_window_menu: |_, _, _, _, _, _, _| {},
|
show_window_menu: |_, _, _, _, _, _, _| {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_size(attrs: &SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)> {
|
||||||
|
attrs
|
||||||
|
.user_data
|
||||||
|
.buffer
|
||||||
|
.as_ref()
|
||||||
|
.map(|&(_, (w, h))| (w as i32, h as i32))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type MyWindowMap = WindowMap<
|
||||||
|
SurfaceData,
|
||||||
|
Roles,
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
fn(&SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
pub fn init_shell(
|
||||||
|
evl: &mut EventLoop, log: ::slog::Logger)
|
||||||
|
-> (
|
||||||
|
CompositorToken<SurfaceData, Roles, ()>,
|
||||||
|
StateToken<ShellState<SurfaceData, Roles, (), ()>>,
|
||||||
|
Rc<RefCell<MyWindowMap>>,
|
||||||
|
) {
|
||||||
|
let (compositor_token, _, _) = compositor_init(evl, surface_implementation(), (), log.clone());
|
||||||
|
|
||||||
|
let window_map = Rc::new(RefCell::new(WindowMap::<_, _, _, (), _>::new(
|
||||||
|
compositor_token,
|
||||||
|
get_size as _,
|
||||||
|
)));
|
||||||
|
|
||||||
|
let (shell_state_token, _, _) = shell_init(
|
||||||
|
evl,
|
||||||
|
compositor_token,
|
||||||
|
shell_implementation(),
|
||||||
|
ShellIData {
|
||||||
|
token: compositor_token,
|
||||||
|
window_map: window_map.clone(),
|
||||||
|
},
|
||||||
|
log.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(compositor_token, shell_state_token, window_map)
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
mod glium;
|
mod glium;
|
||||||
mod implementations;
|
mod implementations;
|
||||||
|
mod window_map;
|
||||||
|
|
||||||
pub use self::glium::GliumDrawer;
|
pub use self::glium::GliumDrawer;
|
||||||
pub use self::implementations::*;
|
pub use self::implementations::*;
|
||||||
|
pub use self::window_map::WindowMap;
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
use smithay::compositor::{CompositorToken, SubsurfaceRole, SurfaceAttributes, TraversalAction};
|
||||||
|
use smithay::compositor::roles::Role;
|
||||||
|
use smithay::shell::{ShellSurfaceRole, ToplevelSurface};
|
||||||
|
use smithay::utils::Rectangle;
|
||||||
|
use wayland_server::Resource;
|
||||||
|
use wayland_server::protocol::wl_surface;
|
||||||
|
|
||||||
|
struct Window<U, R, CID, SD> {
|
||||||
|
location: (i32, i32),
|
||||||
|
surface: Rectangle,
|
||||||
|
toplevel: ToplevelSurface<U, R, CID, SD>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, R, CID, SD> Window<U, R, CID, SD>
|
||||||
|
where
|
||||||
|
U: 'static,
|
||||||
|
R: Role<SubsurfaceRole> + Role<ShellSurfaceRole> + 'static,
|
||||||
|
CID: 'static,
|
||||||
|
SD: 'static,
|
||||||
|
{
|
||||||
|
// Find the topmost surface under this point if any and the location of this point in the surface
|
||||||
|
fn matching<F>(&self, point: (f64, f64), ctoken: CompositorToken<U, R, CID>, get_size: F)
|
||||||
|
-> Option<(wl_surface::WlSurface, (f64, f64))>
|
||||||
|
where
|
||||||
|
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
|
||||||
|
{
|
||||||
|
if !self.surface.contains((point.0 as i32, point.1 as i32)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// need to check more carefully
|
||||||
|
let mut found = None;
|
||||||
|
if let Some(wl_surface) = self.toplevel.get_surface() {
|
||||||
|
ctoken.with_surface_tree_downward(
|
||||||
|
wl_surface,
|
||||||
|
self.location,
|
||||||
|
|wl_surface, attributes, role, &(mut x, mut y)| if let Some((w, h)) = get_size(attributes) {
|
||||||
|
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||||
|
x += subdata.x;
|
||||||
|
y += subdata.y;
|
||||||
|
}
|
||||||
|
let my_rect = Rectangle {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width: w,
|
||||||
|
height: h,
|
||||||
|
};
|
||||||
|
if my_rect.contains((point.0 as i32, point.1 as i32)) {
|
||||||
|
found = wl_surface.clone().map(|s| {
|
||||||
|
(s, (point.0 - my_rect.x as f64, point.1 - my_rect.y as f64))
|
||||||
|
});
|
||||||
|
TraversalAction::Break
|
||||||
|
} else {
|
||||||
|
TraversalAction::DoChildren((x, y))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TraversalAction::SkipChildren
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
found
|
||||||
|
}
|
||||||
|
|
||||||
|
fn self_update<F>(&mut self, ctoken: CompositorToken<U, R, CID>, mut get_size: F)
|
||||||
|
where
|
||||||
|
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
|
||||||
|
{
|
||||||
|
let (base_x, base_y) = self.location;
|
||||||
|
let (mut min_x, mut min_y, mut max_x, mut max_y) = (base_x, base_y, base_x, base_y);
|
||||||
|
if let Some(wl_surface) = self.toplevel.get_surface() {
|
||||||
|
ctoken.with_surface_tree_downward(
|
||||||
|
wl_surface,
|
||||||
|
(base_x, base_y),
|
||||||
|
|_, attributes, role, &(mut x, mut y)| {
|
||||||
|
if let Some((w, h)) = get_size(attributes) {
|
||||||
|
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||||
|
x += subdata.x;
|
||||||
|
y += subdata.y;
|
||||||
|
}
|
||||||
|
// update the bounding box
|
||||||
|
if x < min_x {
|
||||||
|
min_x = x;
|
||||||
|
}
|
||||||
|
if y < min_y {
|
||||||
|
min_y = y;
|
||||||
|
}
|
||||||
|
if x + w > max_x {
|
||||||
|
max_x = x + w;
|
||||||
|
}
|
||||||
|
if y + h > max_y {
|
||||||
|
max_y = y + w;
|
||||||
|
}
|
||||||
|
TraversalAction::DoChildren((x, y))
|
||||||
|
} else {
|
||||||
|
TraversalAction::SkipChildren
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.surface = Rectangle {
|
||||||
|
x: min_x,
|
||||||
|
y: min_y,
|
||||||
|
width: max_x - min_x,
|
||||||
|
height: max_y - min_y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WindowMap<U, R, CID, SD, F> {
|
||||||
|
ctoken: CompositorToken<U, R, CID>,
|
||||||
|
windows: Vec<Window<U, R, CID, SD>>,
|
||||||
|
get_size: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, R, CID, SD, F> WindowMap<U, R, CID, SD, F>
|
||||||
|
where
|
||||||
|
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
|
||||||
|
U: 'static,
|
||||||
|
R: Role<SubsurfaceRole> + Role<ShellSurfaceRole> + 'static,
|
||||||
|
CID: 'static,
|
||||||
|
SD: 'static,
|
||||||
|
{
|
||||||
|
pub fn new(ctoken: CompositorToken<U, R, CID>, get_size: F) -> WindowMap<U, R, CID, SD, F> {
|
||||||
|
WindowMap {
|
||||||
|
ctoken: ctoken,
|
||||||
|
windows: Vec::new(),
|
||||||
|
get_size: get_size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, toplevel: ToplevelSurface<U, R, CID, SD>, location: (i32, i32)) {
|
||||||
|
let mut window = Window {
|
||||||
|
location: location,
|
||||||
|
surface: Rectangle {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
},
|
||||||
|
toplevel: toplevel,
|
||||||
|
};
|
||||||
|
window.self_update(self.ctoken, &self.get_size);
|
||||||
|
self.windows.insert(0, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_surface_under(&self, point: (f64, f64)) -> Option<(wl_surface::WlSurface, (f64, f64))> {
|
||||||
|
for w in &self.windows {
|
||||||
|
if let Some(surface) = w.matching(point, self.ctoken, &self.get_size) {
|
||||||
|
return Some(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_surface_and_bring_to_top(&mut self, point: (f64, f64))
|
||||||
|
-> Option<(wl_surface::WlSurface, (f64, f64))> {
|
||||||
|
let mut found = None;
|
||||||
|
for (i, w) in self.windows.iter().enumerate() {
|
||||||
|
if let Some(surface) = w.matching(point, self.ctoken, &self.get_size) {
|
||||||
|
found = Some((i, surface));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some((i, surface)) = found {
|
||||||
|
let winner = self.windows.remove(i);
|
||||||
|
self.windows.insert(0, winner);
|
||||||
|
Some(surface)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
|
||||||
|
where
|
||||||
|
Func: FnMut(&ToplevelSurface<U, R, CID, SD>, (i32, i32)),
|
||||||
|
{
|
||||||
|
for w in self.windows.iter().rev() {
|
||||||
|
f(&w.toplevel, w.location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh(&mut self) {
|
||||||
|
self.windows.retain(|w| w.toplevel.alive());
|
||||||
|
for w in self.windows.iter_mut() {
|
||||||
|
w.self_update(self.ctoken, &self.get_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.windows.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ extern crate wayland_server;
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
use helpers::{shell_implementation, surface_implementation, GliumDrawer};
|
use helpers::{init_shell, GliumDrawer, MyWindowMap};
|
||||||
use slog::{Drain, Logger};
|
use slog::{Drain, Logger};
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::backend::input::InputBackend;
|
use smithay::backend::input::InputBackend;
|
||||||
|
@ -40,16 +40,8 @@ fn main() {
|
||||||
|
|
||||||
init_shm_global(&mut event_loop, vec![], log.clone());
|
init_shm_global(&mut event_loop, vec![], log.clone());
|
||||||
|
|
||||||
let (compositor_token, _, _) =
|
let (compositor_token, shell_state_token, window_map) = init_shell(&mut event_loop, log.clone());
|
||||||
compositor_init(&mut event_loop, surface_implementation(), (), log.clone());
|
|
||||||
|
|
||||||
let (shell_state_token, _, _) = shell_init(
|
|
||||||
&mut event_loop,
|
|
||||||
compositor_token,
|
|
||||||
shell_implementation(),
|
|
||||||
compositor_token,
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize glium
|
* Initialize glium
|
||||||
|
@ -71,13 +63,13 @@ fn main() {
|
||||||
{
|
{
|
||||||
let screen_dimensions = drawer.get_framebuffer_dimensions();
|
let screen_dimensions = drawer.get_framebuffer_dimensions();
|
||||||
let state = event_loop.state();
|
let state = event_loop.state();
|
||||||
for toplevel_surface in state.get(&shell_state_token).toplevel_surfaces() {
|
window_map
|
||||||
|
.borrow()
|
||||||
|
.with_windows_from_bottom_to_top(|toplevel_surface, initial_place| {
|
||||||
if let Some(wl_surface) = toplevel_surface.get_surface() {
|
if let Some(wl_surface) = toplevel_surface.get_surface() {
|
||||||
// this surface is a root of a subsurface tree that needs to be drawn
|
// this surface is a root of a subsurface tree that needs to be drawn
|
||||||
let initial_place = compositor_token
|
|
||||||
.with_surface_data(wl_surface, |data| data.user_data.location.unwrap_or((0, 0)));
|
|
||||||
compositor_token
|
compositor_token
|
||||||
.with_surface_tree(
|
.with_surface_tree_upward(
|
||||||
wl_surface,
|
wl_surface,
|
||||||
initial_place,
|
initial_place,
|
||||||
|_surface, attributes, role, &(mut x, mut y)| {
|
|_surface, attributes, role, &(mut x, mut y)| {
|
||||||
|
@ -87,7 +79,13 @@ fn main() {
|
||||||
x += subdata.x;
|
x += subdata.x;
|
||||||
y += subdata.y;
|
y += subdata.y;
|
||||||
}
|
}
|
||||||
drawer.render(&mut frame, contents, (w, h), (x, y), screen_dimensions);
|
drawer.render(
|
||||||
|
&mut frame,
|
||||||
|
contents,
|
||||||
|
(w, h),
|
||||||
|
(x, y),
|
||||||
|
screen_dimensions,
|
||||||
|
);
|
||||||
TraversalAction::DoChildren((x, y))
|
TraversalAction::DoChildren((x, y))
|
||||||
} else {
|
} else {
|
||||||
// we are not display, so our children are neither
|
// we are not display, so our children are neither
|
||||||
|
@ -97,11 +95,13 @@ fn main() {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
frame.finish().unwrap();
|
frame.finish().unwrap();
|
||||||
|
|
||||||
event_loop.dispatch(Some(16)).unwrap();
|
event_loop.dispatch(Some(16)).unwrap();
|
||||||
display.flush_clients();
|
display.flush_clients();
|
||||||
|
|
||||||
|
window_map.borrow_mut().refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue