Open new windows with a default size and position (#9204)

This PR changes GPUI to open windows with a default size and location,
and to otherwise inherit from their spawning window.

Note: The linux build now crashes on startup.

Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Ezekiel Warren <zaucy@users.noreply.github.com>
This commit is contained in:
Mikayla Maki
2024-03-12 21:19:51 -07:00
committed by GitHub
co-authored by Nathan Ezekiel Warren
parent 9a2dceeea1
commit e792c1a5c5
30 changed files with 443 additions and 347 deletions
+3 -2
View File
@@ -4,15 +4,16 @@ use std::rc::Rc;
use copypasta::ClipboardProvider;
use crate::platform::PlatformWindow;
use crate::{AnyWindowHandle, CursorStyle, DisplayId, PlatformDisplay, WindowOptions};
use crate::{AnyWindowHandle, CursorStyle, DisplayId, PlatformDisplay, WindowParams};
pub trait Client {
fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>>;
fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>>;
fn display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>>;
fn open_window(
&self,
handle: AnyWindowHandle,
options: WindowOptions,
options: WindowParams,
) -> Box<dyn PlatformWindow>;
fn set_cursor_style(&self, style: CursorStyle);
fn get_clipboard(&self) -> Rc<RefCell<dyn ClipboardProvider>>;
+6 -2
View File
@@ -25,7 +25,7 @@ use crate::{
Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId,
ForegroundExecutor, Keymap, LinuxDispatcher, LinuxTextSystem, Menu, PathPromptOptions,
Platform, PlatformDisplay, PlatformInput, PlatformTextSystem, PlatformWindow, Result,
SemanticVersion, Task, WindowOptions,
SemanticVersion, Task, WindowOptions, WindowParams,
};
use super::x11::X11Client;
@@ -156,6 +156,10 @@ impl Platform for LinuxPlatform {
// todo(linux)
fn unhide_other_apps(&self) {}
fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>> {
self.client.primary_display()
}
fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
self.client.displays()
}
@@ -172,7 +176,7 @@ impl Platform for LinuxPlatform {
fn open_window(
&self,
handle: AnyWindowHandle,
options: WindowOptions,
options: WindowParams,
) -> Box<dyn PlatformWindow> {
self.client.open_window(handle, options)
}
@@ -39,11 +39,12 @@ use crate::platform::linux::client::Client;
use crate::platform::linux::wayland::cursor::Cursor;
use crate::platform::linux::wayland::window::{WaylandDecorationState, WaylandWindow};
use crate::platform::{LinuxPlatformInner, PlatformWindow};
use crate::WindowParams;
use crate::{
platform::linux::wayland::window::WaylandWindowState, AnyWindowHandle, CursorStyle, DisplayId,
KeyDownEvent, KeyUpEvent, Keystroke, Modifiers, ModifiersChangedEvent, MouseButton,
MouseDownEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay,
PlatformInput, Point, ScrollDelta, ScrollWheelEvent, TouchPhase, WindowOptions,
PlatformInput, Point, ScrollDelta, ScrollWheelEvent, TouchPhase,
};
/// Used to convert evdev scancode to xkb scancode
@@ -207,10 +208,14 @@ impl Client for WaylandClient {
unimplemented!()
}
fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>> {
None
}
fn open_window(
&self,
handle: AnyWindowHandle,
options: WindowOptions,
options: WindowParams,
) -> Box<dyn PlatformWindow> {
let mut state = self.state.client_state_inner.borrow_mut();
@@ -22,8 +22,8 @@ use crate::platform::linux::wayland::display::WaylandDisplay;
use crate::platform::{PlatformAtlas, PlatformInputHandler, PlatformWindow};
use crate::scene::Scene;
use crate::{
px, size, Bounds, Modifiers, Pixels, PlatformDisplay, PlatformInput, Point, PromptLevel, Size,
WindowAppearance, WindowBounds, WindowOptions,
px, size, Bounds, GlobalPixels, Modifiers, Pixels, PlatformDisplay, PlatformInput, Point,
PromptLevel, Size, WindowAppearance, WindowParams,
};
#[derive(Default)]
@@ -125,24 +125,9 @@ impl WaylandWindowState {
wl_surf: Arc<wl_surface::WlSurface>,
viewport: Option<wp_viewport::WpViewport>,
toplevel: Arc<xdg_toplevel::XdgToplevel>,
options: WindowOptions,
options: WindowParams,
) -> Self {
if options.bounds == WindowBounds::Maximized {
toplevel.set_maximized();
} else if options.bounds == WindowBounds::Fullscreen {
toplevel.set_fullscreen(None);
}
let bounds: Bounds<u32> = match options.bounds {
WindowBounds::Fullscreen | WindowBounds::Maximized => Bounds {
origin: Point::default(),
size: Size {
width: 500,
height: 500,
}, // todo(implement)
},
WindowBounds::Fixed(bounds) => bounds.map(|p| p.0 as u32),
};
let bounds = options.bounds.map(|p| p.0 as u32);
Self {
surface: Arc::clone(&wl_surf),
@@ -290,8 +275,8 @@ impl HasDisplayHandle for WaylandWindow {
impl PlatformWindow for WaylandWindow {
// todo(linux)
fn bounds(&self) -> WindowBounds {
WindowBounds::Maximized
fn bounds(&self) -> Bounds<GlobalPixels> {
unimplemented!()
}
fn content_size(&self) -> Size<Pixels> {
@@ -331,9 +316,8 @@ impl PlatformWindow for WaylandWindow {
crate::Modifiers::default()
}
// todo(linux)
fn as_any_mut(&mut self) -> &mut dyn Any {
unimplemented!()
self
}
fn set_input_handler(&mut self, input_handler: PlatformInputHandler) {
@@ -379,13 +363,17 @@ impl PlatformWindow for WaylandWindow {
}
fn toggle_full_screen(&self) {
if !self.0.inner.borrow_mut().fullscreen {
if !self.0.inner.borrow().fullscreen {
self.0.toplevel.set_fullscreen(None);
} else {
self.0.toplevel.unset_fullscreen();
}
}
fn is_full_screen(&self) -> bool {
self.0.inner.borrow_mut().fullscreen
}
fn on_request_frame(&self, callback: Box<dyn FnMut()>) {
self.0.callbacks.borrow_mut().request_frame = Some(callback);
}
+16 -7
View File
@@ -13,7 +13,7 @@ use crate::platform::linux::client::Client;
use crate::platform::{LinuxPlatformInner, PlatformWindow};
use crate::{
AnyWindowHandle, Bounds, CursorStyle, DisplayId, PlatformDisplay, PlatformInput, Point,
ScrollDelta, Size, TouchPhase, WindowOptions,
ScrollDelta, Size, TouchPhase,
};
use super::{X11Display, X11Window, X11WindowState, XcbAtoms};
@@ -284,26 +284,35 @@ impl Client for X11Client {
setup
.roots()
.enumerate()
.map(|(root_id, _)| {
Rc::new(X11Display::new(&self.xcb_connection, root_id as i32))
as Rc<dyn PlatformDisplay>
.filter_map(|(root_id, _)| {
Some(
Rc::new(X11Display::new(&self.xcb_connection, root_id as i32)?)
as Rc<dyn PlatformDisplay>,
)
})
.collect()
}
fn display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>> {
Some(Rc::new(X11Display::new(&self.xcb_connection, id.0 as i32)))
Some(Rc::new(X11Display::new(&self.xcb_connection, id.0 as i32)?))
}
fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>> {
Some(Rc::new(
X11Display::new(&self.xcb_connection, self.x_root_index)
.expect("There should always be a root index"),
))
}
fn open_window(
&self,
_handle: AnyWindowHandle,
options: WindowOptions,
params: crate::WindowParams,
) -> Box<dyn PlatformWindow> {
let x_window = self.xcb_connection.generate_id();
let window_ptr = Rc::new(X11WindowState::new(
options,
params,
&self.xcb_connection,
self.x_root_index,
x_window,
@@ -11,9 +11,9 @@ pub(crate) struct X11Display {
}
impl X11Display {
pub(crate) fn new(xc: &xcb::Connection, x_screen_index: i32) -> Self {
let screen = xc.get_setup().roots().nth(x_screen_index as usize).unwrap();
Self {
pub(crate) fn new(xc: &xcb::Connection, x_screen_index: i32) -> Option<Self> {
let screen = xc.get_setup().roots().nth(x_screen_index as usize)?;
Some(Self {
x_screen_index,
bounds: Bounds {
origin: Default::default(),
@@ -23,7 +23,7 @@ impl X11Display {
},
},
uuid: Uuid::from_bytes([0; 16]),
}
})
}
}
+21 -29
View File
@@ -4,7 +4,7 @@
use crate::{
platform::blade::BladeRenderer, size, Bounds, GlobalPixels, Modifiers, Pixels, PlatformAtlas,
PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, PromptLevel,
Scene, Size, WindowAppearance, WindowBounds, WindowOptions,
Scene, Size, WindowAppearance, WindowOptions, WindowParams,
};
use blade_graphics as gpu;
use parking_lot::Mutex;
@@ -138,13 +138,13 @@ impl rwh::HasDisplayHandle for X11Window {
impl X11WindowState {
pub fn new(
options: WindowOptions,
params: WindowParams,
xcb_connection: &Rc<xcb::Connection>,
x_main_screen_index: i32,
x_window: x::Window,
atoms: &XcbAtoms,
) -> Self {
let x_screen_index = options
let x_screen_index = params
.display_id
.map_or(x_main_screen_index, |did| did.0 as i32);
let screen = xcb_connection
@@ -175,32 +175,21 @@ impl X11WindowState {
),
];
let bounds = match options.bounds {
WindowBounds::Fullscreen | WindowBounds::Maximized => Bounds {
origin: Point::default(),
size: Size {
width: screen.width_in_pixels() as i32,
height: screen.height_in_pixels() as i32,
},
},
WindowBounds::Fixed(bounds) => bounds.map(|p| p.0 as i32),
};
xcb_connection.send_request(&x::CreateWindow {
depth: x::COPY_FROM_PARENT as u8,
wid: x_window,
parent: screen.root(),
x: bounds.origin.x as i16,
y: bounds.origin.y as i16,
width: bounds.size.width as u16,
height: bounds.size.height as u16,
x: params.bounds.origin.x.0 as i16,
y: params.bounds.origin.y.0 as i16,
width: params.bounds.size.width.0 as u16,
height: params.bounds.size.height.0 as u16,
border_width: 0,
class: x::WindowClass::InputOutput,
visual: screen.root_visual(),
value_list: &xcb_values,
});
if let Some(titlebar) = options.titlebar {
if let Some(titlebar) = params.titlebar {
if let Some(title) = titlebar.title {
xcb_connection.send_request(&x::ChangeProperty {
mode: x::PropMode::Replace,
@@ -250,12 +239,12 @@ impl X11WindowState {
Self {
xcb_connection: xcb_connection.clone(),
display: Rc::new(X11Display::new(xcb_connection, x_screen_index)),
display: Rc::new(X11Display::new(xcb_connection, x_screen_index).unwrap()),
raw,
x_window,
callbacks: RefCell::new(Callbacks::default()),
inner: RefCell::new(LinuxWindowInner {
bounds,
bounds: params.bounds.map(|v| v.0 as i32),
scale_factor: 1.0,
renderer: BladeRenderer::new(gpu, gpu_extent),
input_handler: None,
@@ -339,14 +328,12 @@ impl X11WindowState {
}
impl PlatformWindow for X11Window {
fn bounds(&self) -> WindowBounds {
WindowBounds::Fixed(
self.0
.inner
.borrow_mut()
.bounds
.map(|v| GlobalPixels(v as f32)),
)
fn bounds(&self) -> Bounds<GlobalPixels> {
self.0
.inner
.borrow_mut()
.bounds
.map(|v| GlobalPixels(v as f32))
}
fn content_size(&self) -> Size<Pixels> {
@@ -454,6 +441,11 @@ impl PlatformWindow for X11Window {
unimplemented!()
}
// todo(linux)
fn is_full_screen(&self) -> bool {
unimplemented!()
}
fn on_request_frame(&self, callback: Box<dyn FnMut()>) {
self.0.callbacks.borrow_mut().request_frame = Some(callback);
}