wayland: Window controls and drag (#11525)
Based on https://github.com/zed-industries/zed/pull/11046 - Partially fixes #10346 - Fixes https://github.com/zed-industries/zed/issues/9964 ## Features Window buttons  Window drag  Native window context menu  ### Limitations - No resizing - Wayland only (though X11 always has window decorations) ### Technical This PR adds three APIs to gpui. 1. `show_window_menu`: Triggers the native title bar context menu. 2. `start_system_move`: Tells the compositor to start dragging the window. 3. `should_render_window_controls`: Whether the compositor doesn't support server side decorations. These APIs have only been implemented for Wayland, but they should be portable to other platforms. Release Notes: - N/A --------- Co-authored-by: Akilan Elango <akilan1997@gmail.com>
This commit is contained in:
parent
db89353193
commit
d1ee2d0749
13 changed files with 277 additions and 11 deletions
|
@ -23,6 +23,7 @@ use wayland_client::globals::{registry_queue_init, GlobalList, GlobalListContent
|
|||
use wayland_client::protocol::wl_callback::{self, WlCallback};
|
||||
use wayland_client::protocol::wl_data_device_manager::DndAction;
|
||||
use wayland_client::protocol::wl_pointer::{AxisRelativeDirection, AxisSource};
|
||||
use wayland_client::protocol::wl_seat::WlSeat;
|
||||
use wayland_client::protocol::{
|
||||
wl_data_device, wl_data_device_manager, wl_data_offer, wl_data_source, wl_output, wl_region,
|
||||
};
|
||||
|
@ -80,6 +81,7 @@ pub struct Globals {
|
|||
pub data_device_manager: Option<wl_data_device_manager::WlDataDeviceManager>,
|
||||
pub wm_base: xdg_wm_base::XdgWmBase,
|
||||
pub shm: wl_shm::WlShm,
|
||||
pub seat: wl_seat::WlSeat,
|
||||
pub viewporter: Option<wp_viewporter::WpViewporter>,
|
||||
pub fractional_scale_manager:
|
||||
Option<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1>,
|
||||
|
@ -93,6 +95,7 @@ impl Globals {
|
|||
globals: GlobalList,
|
||||
executor: ForegroundExecutor,
|
||||
qh: QueueHandle<WaylandClientStatePtr>,
|
||||
seat: wl_seat::WlSeat,
|
||||
) -> Self {
|
||||
Globals {
|
||||
activation: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
|
@ -113,6 +116,7 @@ impl Globals {
|
|||
)
|
||||
.ok(),
|
||||
shm: globals.bind(&qh, 1..=1, ()).unwrap(),
|
||||
seat,
|
||||
wm_base: globals.bind(&qh, 1..=1, ()).unwrap(),
|
||||
viewporter: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
fractional_scale_manager: globals.bind(&qh, 1..=1, ()).ok(),
|
||||
|
@ -193,6 +197,10 @@ impl WaylandClientStatePtr {
|
|||
.expect("The pointer should always be valid when dispatching in wayland")
|
||||
}
|
||||
|
||||
pub fn get_serial(&self, kind: SerialKind) -> u32 {
|
||||
self.0.upgrade().unwrap().borrow().serial_tracker.get(kind)
|
||||
}
|
||||
|
||||
pub fn drop_window(&self, surface_id: &ObjectId) {
|
||||
let mut client = self.get_client();
|
||||
let mut state = client.borrow_mut();
|
||||
|
@ -303,7 +311,12 @@ impl WaylandClient {
|
|||
});
|
||||
|
||||
let seat = seat.unwrap();
|
||||
let globals = Globals::new(globals, common.foreground_executor.clone(), qh.clone());
|
||||
let globals = Globals::new(
|
||||
globals,
|
||||
common.foreground_executor.clone(),
|
||||
qh.clone(),
|
||||
seat.clone(),
|
||||
);
|
||||
|
||||
let data_device = globals
|
||||
.data_device_manager
|
||||
|
@ -962,6 +975,7 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientStatePtr {
|
|||
} => {
|
||||
state.serial_tracker.update(SerialKind::MouseEnter, serial);
|
||||
state.mouse_location = Some(point(px(surface_x as f32), px(surface_y as f32)));
|
||||
state.button_pressed = None;
|
||||
|
||||
if let Some(window) = get_window(&mut state, &surface.id()) {
|
||||
state.mouse_focused_window = Some(window.clone());
|
||||
|
@ -990,6 +1004,7 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientStatePtr {
|
|||
});
|
||||
state.mouse_focused_window = None;
|
||||
state.mouse_location = None;
|
||||
state.button_pressed = None;
|
||||
|
||||
drop(state);
|
||||
focused_window.handle_input(input);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue