1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-25 14:22:37 +03:00

Window progress: no WindowInner though

This commit is contained in:
Timmy Xiao 2024-01-04 16:13:16 -05:00 committed by Wez Furlong
parent d49a27d5a7
commit 6911ed0943
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
2 changed files with 205 additions and 16 deletions

View File

@ -1,26 +1,29 @@
// TODO: change this
#![allow(dead_code, unused)]
use std::{borrow::BorrowMut, cell::RefCell, os::fd::AsRawFd};
use std::{borrow::BorrowMut, cell::RefCell, os::fd::AsRawFd, sync::atomic::AtomicUsize};
use anyhow::{Context, bail};
use mio::{unix::SourceFd, Events, Interest, Poll, Token};
use smithay_client_toolkit::{
delegate_registry,
registry::{ProvidesRegistryState, RegistryState},
registry_handlers,
registry_handlers, delegate_compositor, compositor::CompositorHandler, output::OutputHandler, delegate_xdg_shell, delegate_xdg_window, shell::xdg::window::WindowHandler,
};
use wayland_client::{globals::registry_queue_init, Connection, EventQueue, backend::{protocol::ProtocolError, WaylandError}};
use wayland_client::{globals::{registry_queue_init, GlobalList}, Connection, EventQueue, backend::{protocol::ProtocolError, WaylandError}};
use crate::{spawn::SPAWN_QUEUE, ConnectionOps};
pub struct WaylandConnection {
should_terminate: RefCell<bool>,
event_queue: RefCell<EventQueue<WaylandState>>,
pub(crate) should_terminate: RefCell<bool>,
pub(crate) next_window_id: AtomicUsize,
wayland_state: RefCell<WaylandState>,
pub(crate) event_queue: RefCell<EventQueue<WaylandState>>,
pub(crate) globals: RefCell<GlobalList>,
pub(crate) wayland_state: RefCell<WaylandState>,
}
struct WaylandState {
pub (crate) struct WaylandState {
registry_state: RegistryState,
}
@ -35,7 +38,11 @@ impl WaylandConnection {
};
let wayland_connection = WaylandConnection {
should_terminate: RefCell::new(false),
next_window_id: AtomicUsize::new(1),
event_queue: RefCell::new(event_queue),
globals: RefCell::new(globals),
wayland_state: RefCell::new(wayland_state),
};
@ -118,6 +125,11 @@ impl WaylandConnection {
Ok(())
}
pub(crate) fn next_window_id(&self) -> usize {
self.next_window_id
.fetch_add(1, ::std::sync::atomic::Ordering::Relaxed)
}
}
impl ProvidesRegistryState for WaylandState {
@ -128,9 +140,81 @@ impl ProvidesRegistryState for WaylandState {
registry_handlers!();
}
impl CompositorHandler for WaylandState {
fn scale_factor_changed(
&mut self,
conn: &Connection,
qh: &wayland_client::QueueHandle<Self>,
surface: &wayland_client::protocol::wl_surface::WlSurface,
new_factor: i32,
) {
todo!()
}
fn frame(
&mut self,
conn: &Connection,
qh: &wayland_client::QueueHandle<Self>,
surface: &wayland_client::protocol::wl_surface::WlSurface,
time: u32,
) {
todo!()
}
}
impl OutputHandler for WaylandState {
fn output_state(&mut self) -> &mut smithay_client_toolkit::output::OutputState {
todo!()
}
fn new_output(
&mut self,
conn: &Connection,
qh: &wayland_client::QueueHandle<Self>,
output: wayland_client::protocol::wl_output::WlOutput,
) {
todo!()
}
fn update_output(
&mut self,
conn: &Connection,
qh: &wayland_client::QueueHandle<Self>,
output: wayland_client::protocol::wl_output::WlOutput,
) {
todo!()
}
fn output_destroyed(
&mut self,
conn: &Connection,
qh: &wayland_client::QueueHandle<Self>,
output: wayland_client::protocol::wl_output::WlOutput,
) {
todo!()
}
}
impl WindowHandler for WaylandState {
fn request_close(&mut self, conn: &Connection, qh: &wayland_client::QueueHandle<Self>, window: &smithay_client_toolkit::shell::xdg::window::Window) {
todo!()
}
fn configure(
&mut self,
conn: &Connection,
qh: &wayland_client::QueueHandle<Self>,
window: &smithay_client_toolkit::shell::xdg::window::Window,
configure: smithay_client_toolkit::shell::xdg::window::WindowConfigure,
serial: u32,
) {
todo!()
}
}
impl ConnectionOps for WaylandConnection {
fn name(&self) -> String {
todo!()
"Wayland".to_string()
}
fn terminate_message_loop(&self) {
@ -143,4 +227,7 @@ impl ConnectionOps for WaylandConnection {
}
}
delegate_xdg_shell!(WaylandState);
delegate_xdg_window!(WaylandState);
delegate_compositor!(WaylandState);
delegate_registry!(WaylandState);

View File

@ -3,14 +3,28 @@
use std::any::Any;
use std::rc::Rc;
use std::sync::Arc;
use std::sync::Mutex;
use anyhow::anyhow;
use config::configuration;
use config::ConfigHandle;
use promise::Future;
use raw_window_handle::HasRawDisplayHandle;
use raw_window_handle::HasRawWindowHandle;
use smithay_client_toolkit::compositor::CompositorState;
use smithay_client_toolkit::registry::ProvidesRegistryState;
use smithay_client_toolkit::shell::WaylandSurface;
use smithay_client_toolkit::shell::xdg::XdgShell;
use smithay_client_toolkit::shell::xdg::window::DecorationMode;
use smithay_client_toolkit::shell::xdg::window::WindowDecorations as Decorations;
use wayland_client::globals::GlobalList;
use wezterm_font::FontConfiguration;
use wezterm_input_types::WindowDecorations;
use crate::wayland::WaylandConnection;
use crate::Clipboard;
use crate::ConnectionOps;
use crate::MouseCursor;
use crate::RequestedWindowGeometry;
use crate::Window;
@ -22,18 +36,97 @@ pub struct WaylandWindow(usize);
impl WaylandWindow {
pub async fn new_window<F>(
_class_name: &str,
_name: &str,
_geometry: RequestedWindowGeometry,
_config: Option<&ConfigHandle>,
_font_config: Rc<FontConfiguration>,
_event_handler: F,
class_name: &str,
name: &str,
geometry: RequestedWindowGeometry,
config: Option<&ConfigHandle>,
font_config: Rc<FontConfiguration>,
event_handler: F,
) -> anyhow::Result<Window>
where
F: 'static + FnMut(WindowEvent, &Window),
{
log::debug!("Creating a window");
todo!("WaylandWindow::new_window")
log::trace!("Creating a window");
let config = match config {
Some(c) => c.clone(),
None => config::configuration(),
};
let conn = WaylandConnection::get()
.ok_or_else(|| {
anyhow!(
"new_window must be called on the gui thread after Connection:init has succeed",
)
})?
.wayland();
let window_id = conn.next_window_id();
// let pending_event = Arc::new(Mutex::new(PendingEvent::default()));
// let (pending_first_configure, wait_configure) = async_channel::bounded(1);
let qh = conn.event_queue.borrow().handle();
let globals = conn.globals.borrow();
let compositor = CompositorState::bind(&globals, &qh)?;
let surface = compositor.create_surface(&qh);
let xdg_shell = XdgShell::bind(&globals, &qh)?;
let window = xdg_shell.create_window(
surface,
Decorations::RequestServer,
&qh,
);
window.set_app_id(class_name.to_string());
// TODO: investigate the resizable thing
// window.set_resizable(true);
window.set_title(name.to_string());
let decorations = config.window_decorations;
let decor_mode = if decorations == WindowDecorations::NONE {
None
} else if decorations == WindowDecorations::default() {
Some(DecorationMode::Server)
} else {
Some(DecorationMode::Client)
};
window.request_decoration_mode(decor_mode);
// TODO: I don't know anything about the frame thing
// window.set_frame_config(ConceptConfig {
window.set_min_size(Some((32, 32)));
//
// TODO:
// let copy_and_paste = CopyAndPaste::create();
// let pending_mouse = PendingMouse::create(window_id, &copy_and_paste);
// conn.pointer.borrow().add_window(&surface, &pending_mouse);
// TODO: WindowInner
let window_handle = Window::Wayland(WaylandWindow(window_id));
// TODO: assign window inner
//
// window.set_decorate(if decorations == WindowDecorations::NONE {
// Decorations::None
// } else if decorations == WindowDecorations::default() {
// Decorations::FollowServer
// } else {
// // SCTK/Wayland don't allow more nuance than "decorations are hidden",
// // so if we have a mixture of things, then we need to force our
// // client side decoration rendering.
// Decorations::ClientSide
// });
window.commit();
Ok(window_handle)
}
}
@ -121,3 +214,12 @@ unsafe impl HasRawWindowHandle for WaylandWindow {
todo!()
}
}
#[derive(Default, Clone, Debug)]
struct PendingEvent {
close: bool,
had_configure_event: bool,
configure: Option<(u32, u32)>,
dpi: Option<i32>,
// window_state: Option<WindowState>,
}