2023-01-05 06:58:08 -07:00
|
|
|
use std::collections::VecDeque;
|
2024-09-21 20:27:12 +03:00
|
|
|
use std::iter;
|
2023-01-05 06:58:08 -07:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
2024-11-12 10:56:20 +03:00
|
|
|
use super::event_loop::EventLoopProxy;
|
2024-09-21 20:27:12 +03:00
|
|
|
use super::{ActiveEventLoop, RedoxSocket, WindowProperties};
|
2023-12-25 07:20:52 +01:00
|
|
|
use crate::cursor::Cursor;
|
2024-11-21 17:37:03 +01:00
|
|
|
use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
2024-09-06 17:20:11 +03:00
|
|
|
use crate::error::{NotSupportedError, RequestError};
|
2024-09-21 20:27:12 +03:00
|
|
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
|
|
|
|
use crate::window::{self, ImePurpose, Window as CoreWindow, WindowId};
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
// These values match the values uses in the `window_new` function in orbital:
|
|
|
|
|
// https://gitlab.redox-os.org/redox-os/orbital/-/blob/master/src/scheme.rs
|
|
|
|
|
const ORBITAL_FLAG_ASYNC: char = 'a';
|
|
|
|
|
const ORBITAL_FLAG_BACK: char = 'b';
|
|
|
|
|
const ORBITAL_FLAG_FRONT: char = 'f';
|
2024-02-10 17:40:06 -07:00
|
|
|
const ORBITAL_FLAG_HIDDEN: char = 'h';
|
2023-01-05 06:58:08 -07:00
|
|
|
const ORBITAL_FLAG_BORDERLESS: char = 'l';
|
2024-02-10 17:40:06 -07:00
|
|
|
const ORBITAL_FLAG_MAXIMIZED: char = 'm';
|
2023-01-05 06:58:08 -07:00
|
|
|
const ORBITAL_FLAG_RESIZABLE: char = 'r';
|
|
|
|
|
const ORBITAL_FLAG_TRANSPARENT: char = 't';
|
|
|
|
|
|
2025-03-03 08:40:04 +01:00
|
|
|
#[derive(Debug)]
|
2023-01-05 06:58:08 -07:00
|
|
|
pub struct Window {
|
|
|
|
|
window_socket: Arc<RedoxSocket>,
|
|
|
|
|
redraws: Arc<Mutex<VecDeque<WindowId>>>,
|
|
|
|
|
destroys: Arc<Mutex<VecDeque<WindowId>>>,
|
2024-11-12 10:56:20 +03:00
|
|
|
event_loop_proxy: Arc<EventLoopProxy>,
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Window {
|
2024-01-13 21:36:53 +01:00
|
|
|
pub(crate) fn new(
|
2024-01-31 17:29:59 +04:00
|
|
|
el: &ActiveEventLoop,
|
2023-01-05 06:58:08 -07:00
|
|
|
attrs: window::WindowAttributes,
|
2024-09-06 17:20:11 +03:00
|
|
|
) -> Result<Self, RequestError> {
|
2024-09-21 20:27:12 +03:00
|
|
|
let scale = 1.;
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
let (x, y) = if let Some(pos) = attrs.position {
|
|
|
|
|
pos.to_physical::<i32>(scale).into()
|
|
|
|
|
} else {
|
|
|
|
|
// These coordinates are a special value to center the window.
|
|
|
|
|
(-1, -1)
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-04 15:04:48 +02:00
|
|
|
let (w, h): (u32, u32) = if let Some(size) = attrs.surface_size {
|
2023-01-05 06:58:08 -07:00
|
|
|
size.to_physical::<u32>(scale).into()
|
|
|
|
|
} else {
|
|
|
|
|
(1024, 768)
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-04 15:04:48 +02:00
|
|
|
// TODO: min/max surface_size
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
// Async by default.
|
|
|
|
|
let mut flag_str = ORBITAL_FLAG_ASYNC.to_string();
|
|
|
|
|
|
2024-02-10 17:40:06 -07:00
|
|
|
if attrs.maximized {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_MAXIMIZED);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
if attrs.resizable {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_RESIZABLE);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 17:40:06 -07:00
|
|
|
// TODO: fullscreen
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
if attrs.transparent {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_TRANSPARENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !attrs.decorations {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_BORDERLESS);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 17:40:06 -07:00
|
|
|
if !attrs.visible {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_HIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
match attrs.window_level {
|
|
|
|
|
window::WindowLevel::AlwaysOnBottom => {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_BACK);
|
|
|
|
|
},
|
|
|
|
|
window::WindowLevel::Normal => {},
|
|
|
|
|
window::WindowLevel::AlwaysOnTop => {
|
|
|
|
|
flag_str.push(ORBITAL_FLAG_FRONT);
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: window_icon
|
|
|
|
|
|
|
|
|
|
// Open window.
|
|
|
|
|
let window = RedoxSocket::orbital(&WindowProperties {
|
|
|
|
|
flags: &flag_str,
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
w,
|
|
|
|
|
h,
|
|
|
|
|
title: &attrs.title,
|
|
|
|
|
})
|
|
|
|
|
.expect("failed to open window");
|
|
|
|
|
|
|
|
|
|
// Add to event socket.
|
|
|
|
|
el.event_socket
|
|
|
|
|
.write(&syscall::Event {
|
|
|
|
|
id: window.fd,
|
|
|
|
|
flags: syscall::EventFlags::EVENT_READ,
|
|
|
|
|
data: window.fd,
|
|
|
|
|
})
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
let window_socket = Arc::new(window);
|
|
|
|
|
|
|
|
|
|
// Notify event thread that this window was created, it will send some default events.
|
|
|
|
|
{
|
|
|
|
|
let mut creates = el.creates.lock().unwrap();
|
|
|
|
|
creates.push_back(window_socket.clone());
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-12 10:56:20 +03:00
|
|
|
el.event_loop_proxy.wake_socket.wake().unwrap();
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
|
window_socket,
|
|
|
|
|
redraws: el.redraws.clone(),
|
|
|
|
|
destroys: el.destroys.clone(),
|
2024-11-12 10:56:20 +03:00
|
|
|
event_loop_proxy: el.event_loop_proxy.clone(),
|
2023-01-05 06:58:08 -07:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-06 17:20:11 +03:00
|
|
|
fn get_flag(&self, flag: char) -> Result<bool, RequestError> {
|
2024-02-10 17:40:06 -07:00
|
|
|
let mut buf: [u8; 4096] = [0; 4096];
|
2024-09-06 17:20:11 +03:00
|
|
|
let path = self.window_socket.fpath(&mut buf).map_err(|err| os_error!(format!("{err}")))?;
|
2024-02-10 17:40:06 -07:00
|
|
|
let properties = WindowProperties::new(path);
|
|
|
|
|
Ok(properties.flags.contains(flag))
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-06 17:20:11 +03:00
|
|
|
fn set_flag(&self, flag: char, value: bool) -> Result<(), RequestError> {
|
2024-02-10 17:40:06 -07:00
|
|
|
self.window_socket
|
|
|
|
|
.write(format!("F,{flag},{}", if value { 1 } else { 0 }).as_bytes())
|
2024-09-06 17:20:11 +03:00
|
|
|
.map_err(|err| os_error!(format!("{err}")))?;
|
2024-02-10 17:40:06 -07:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
|
|
|
|
let handle = rwh_06::OrbitalWindowHandle::new({
|
|
|
|
|
let window = self.window_socket.fd as *mut _;
|
|
|
|
|
std::ptr::NonNull::new(window).expect("orbital fd should never be null")
|
|
|
|
|
});
|
|
|
|
|
Ok(rwh_06::RawWindowHandle::Orbital(handle))
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn raw_display_handle_rwh_06(&self) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
|
|
|
|
Ok(rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl CoreWindow for Window {
|
2024-10-08 15:29:40 +02:00
|
|
|
fn id(&self) -> WindowId {
|
|
|
|
|
WindowId::from_raw(self.window_socket.fd)
|
2024-08-23 23:40:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn primary_monitor(&self) -> Option<CoreMonitorHandle> {
|
2024-09-21 20:27:12 +03:00
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
2024-09-21 20:27:12 +03:00
|
|
|
Box::new(iter::empty())
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn current_monitor(&self) -> Option<CoreMonitorHandle> {
|
2024-09-21 20:27:12 +03:00
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn scale_factor(&self) -> f64 {
|
2024-09-21 20:27:12 +03:00
|
|
|
1.
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn request_redraw(&self) {
|
2024-10-08 15:29:40 +02:00
|
|
|
let window_id = self.id();
|
2023-01-05 06:58:08 -07:00
|
|
|
let mut redraws = self.redraws.lock().unwrap();
|
|
|
|
|
if !redraws.contains(&window_id) {
|
|
|
|
|
redraws.push_back(window_id);
|
|
|
|
|
|
2024-11-12 10:56:20 +03:00
|
|
|
self.event_loop_proxy.wake_socket.wake().unwrap();
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-22 08:08:53 +04:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn pre_present_notify(&self) {}
|
2023-06-22 08:08:53 +04:00
|
|
|
|
2023-05-28 20:02:59 +02:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn reset_dead_keys(&self) {
|
2023-05-28 20:02:59 +02:00
|
|
|
// TODO?
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-11-21 17:37:03 +01:00
|
|
|
fn surface_position(&self) -> PhysicalPosition<i32> {
|
|
|
|
|
// TODO: adjust for window decorations
|
|
|
|
|
(0, 0).into()
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-06 17:20:11 +03:00
|
|
|
fn outer_position(&self) -> Result<PhysicalPosition<i32>, RequestError> {
|
2024-11-21 17:37:03 +01:00
|
|
|
let mut buf: [u8; 4096] = [0; 4096];
|
|
|
|
|
let path = self.window_socket.fpath(&mut buf).expect("failed to read properties");
|
|
|
|
|
let properties = WindowProperties::new(path);
|
|
|
|
|
Ok((properties.x, properties.y).into())
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_outer_position(&self, position: Position) {
|
2023-01-05 06:58:08 -07:00
|
|
|
// TODO: adjust for window decorations
|
|
|
|
|
let (x, y): (i32, i32) = position.to_physical::<i32>(self.scale_factor()).into();
|
2023-01-27 07:18:58 +03:00
|
|
|
self.window_socket.write(format!("P,{x},{y}").as_bytes()).expect("failed to set position");
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-04 15:04:48 +02:00
|
|
|
fn surface_size(&self) -> PhysicalSize<u32> {
|
2023-01-05 06:58:08 -07:00
|
|
|
let mut buf: [u8; 4096] = [0; 4096];
|
|
|
|
|
let path = self.window_socket.fpath(&mut buf).expect("failed to read properties");
|
|
|
|
|
let properties = WindowProperties::new(path);
|
|
|
|
|
(properties.w, properties.h).into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-04 15:04:48 +02:00
|
|
|
fn request_surface_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
2023-01-05 06:58:08 -07:00
|
|
|
let (w, h): (u32, u32) = size.to_physical::<u32>(self.scale_factor()).into();
|
2023-01-27 07:18:58 +03:00
|
|
|
self.window_socket.write(format!("S,{w},{h}").as_bytes()).expect("failed to set size");
|
2023-07-10 04:02:26 +00:00
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn outer_size(&self) -> PhysicalSize<u32> {
|
2023-01-05 06:58:08 -07:00
|
|
|
// TODO: adjust for window decorations
|
2024-09-04 15:04:48 +02:00
|
|
|
self.surface_size()
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2024-11-21 17:37:03 +01:00
|
|
|
fn safe_area(&self) -> PhysicalInsets<u32> {
|
|
|
|
|
PhysicalInsets::new(0, 0, 0, 0)
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-09-04 15:04:48 +02:00
|
|
|
fn set_min_surface_size(&self, _: Option<Size>) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-04 15:04:48 +02:00
|
|
|
fn set_max_surface_size(&self, _: Option<Size>) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn title(&self) -> String {
|
2023-01-05 06:58:08 -07:00
|
|
|
let mut buf: [u8; 4096] = [0; 4096];
|
|
|
|
|
let path = self.window_socket.fpath(&mut buf).expect("failed to read properties");
|
|
|
|
|
let properties = WindowProperties::new(path);
|
|
|
|
|
properties.title.to_string()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_title(&self, title: &str) {
|
2023-01-27 07:18:58 +03:00
|
|
|
self.window_socket.write(format!("T,{title}").as_bytes()).expect("failed to set title");
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2023-01-15 23:39:36 +03:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_transparent(&self, transparent: bool) {
|
2024-02-10 17:40:06 -07:00
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_TRANSPARENT, transparent);
|
|
|
|
|
}
|
2023-01-15 23:39:36 +03:00
|
|
|
|
2023-10-08 22:53:15 +03:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_blur(&self, _blur: bool) {}
|
2023-10-08 22:53:15 +03:00
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_visible(&self, visible: bool) {
|
2024-02-10 17:40:06 -07:00
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_HIDDEN, !visible);
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn is_visible(&self) -> Option<bool> {
|
2024-02-10 17:40:06 -07:00
|
|
|
Some(!self.get_flag(ORBITAL_FLAG_HIDDEN).unwrap_or(false))
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-04 15:04:48 +02:00
|
|
|
fn surface_resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
2023-01-05 06:58:08 -07:00
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-04 15:04:48 +02:00
|
|
|
fn set_surface_resize_increments(&self, _increments: Option<Size>) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_resizable(&self, resizeable: bool) {
|
2024-02-10 17:40:06 -07:00
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_RESIZABLE, resizeable);
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn is_resizable(&self) -> bool {
|
2024-02-10 17:40:06 -07:00
|
|
|
self.get_flag(ORBITAL_FLAG_RESIZABLE).unwrap_or(false)
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_minimized(&self, _minimized: bool) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
2023-01-19 23:39:04 +02:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn is_minimized(&self) -> Option<bool> {
|
2023-01-19 23:39:04 +02:00
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_maximized(&self, maximized: bool) {
|
2024-02-10 17:40:06 -07:00
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_MAXIMIZED, maximized);
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn is_maximized(&self) -> bool {
|
2024-02-10 17:40:06 -07:00
|
|
|
self.get_flag(ORBITAL_FLAG_MAXIMIZED).unwrap_or(false)
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_fullscreen(&self, _monitor: Option<Fullscreen>) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
2024-08-23 23:40:27 +03:00
|
|
|
fn fullscreen(&self) -> Option<Fullscreen> {
|
2023-01-05 06:58:08 -07:00
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_decorations(&self, decorations: bool) {
|
2024-02-10 17:40:06 -07:00
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_BORDERLESS, !decorations);
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn is_decorated(&self) -> bool {
|
2024-02-10 17:40:06 -07:00
|
|
|
!self.get_flag(ORBITAL_FLAG_BORDERLESS).unwrap_or(false)
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_window_level(&self, level: window::WindowLevel) {
|
2024-02-10 17:40:06 -07:00
|
|
|
match level {
|
|
|
|
|
window::WindowLevel::AlwaysOnBottom => {
|
|
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_BACK, true);
|
|
|
|
|
},
|
|
|
|
|
window::WindowLevel::Normal => {
|
|
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_BACK, false);
|
|
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_FRONT, false);
|
|
|
|
|
},
|
|
|
|
|
window::WindowLevel::AlwaysOnTop => {
|
|
|
|
|
let _ = self.set_flag(ORBITAL_FLAG_FRONT, true);
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_ime_cursor_area(&self, _position: Position, _size: Size) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_ime_allowed(&self, _allowed: bool) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
2023-01-29 16:46:46 +01:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
2023-01-29 16:46:46 +01:00
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn focus_window(&self) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_cursor(&self, _: Cursor) {}
|
2023-12-16 22:02:17 +02:00
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-09-06 17:20:11 +03:00
|
|
|
fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> {
|
|
|
|
|
Err(NotSupportedError::new("set_cursor_position is not supported").into())
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-06 17:20:11 +03:00
|
|
|
fn set_cursor_grab(&self, mode: window::CursorGrabMode) -> Result<(), RequestError> {
|
2024-02-10 17:40:06 -07:00
|
|
|
let (grab, relative) = match mode {
|
|
|
|
|
window::CursorGrabMode::None => (false, false),
|
|
|
|
|
window::CursorGrabMode::Confined => (true, false),
|
|
|
|
|
window::CursorGrabMode::Locked => (true, true),
|
|
|
|
|
};
|
|
|
|
|
self.window_socket
|
|
|
|
|
.write(format!("M,G,{}", if grab { 1 } else { 0 }).as_bytes())
|
2024-09-06 17:20:11 +03:00
|
|
|
.map_err(|err| os_error!(format!("{err}")))?;
|
2024-02-10 17:40:06 -07:00
|
|
|
self.window_socket
|
|
|
|
|
.write(format!("M,R,{}", if relative { 1 } else { 0 }).as_bytes())
|
2024-09-06 17:20:11 +03:00
|
|
|
.map_err(|err| os_error!(format!("{err}")))?;
|
2024-02-10 17:40:06 -07:00
|
|
|
Ok(())
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_cursor_visible(&self, visible: bool) {
|
2024-02-10 17:40:06 -07:00
|
|
|
let _ = self.window_socket.write(format!("M,C,{}", if visible { 1 } else { 0 }).as_bytes());
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-06 17:20:11 +03:00
|
|
|
fn drag_window(&self) -> Result<(), RequestError> {
|
|
|
|
|
self.window_socket.write(b"D").map_err(|err| os_error!(format!("{err}")))?;
|
2024-02-10 17:40:06 -07:00
|
|
|
Ok(())
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2023-01-11 18:07:09 +01:00
|
|
|
#[inline]
|
2024-09-06 17:20:11 +03:00
|
|
|
fn drag_resize_window(&self, direction: window::ResizeDirection) -> Result<(), RequestError> {
|
2024-02-10 17:40:06 -07:00
|
|
|
let arg = match direction {
|
|
|
|
|
window::ResizeDirection::East => "R",
|
|
|
|
|
window::ResizeDirection::North => "T",
|
|
|
|
|
window::ResizeDirection::NorthEast => "T,R",
|
|
|
|
|
window::ResizeDirection::NorthWest => "T,L",
|
|
|
|
|
window::ResizeDirection::South => "B",
|
|
|
|
|
window::ResizeDirection::SouthEast => "B,R",
|
|
|
|
|
window::ResizeDirection::SouthWest => "B,L",
|
|
|
|
|
window::ResizeDirection::West => "L",
|
|
|
|
|
};
|
|
|
|
|
self.window_socket
|
2024-11-22 13:14:11 -08:00
|
|
|
.write(format!("D,{arg}").as_bytes())
|
2024-09-06 17:20:11 +03:00
|
|
|
.map_err(|err| os_error!(format!("{err}")))?;
|
2024-02-10 17:40:06 -07:00
|
|
|
Ok(())
|
2023-01-11 18:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
2023-10-11 01:16:16 +03:30
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn show_window_menu(&self, _position: Position) {}
|
2023-10-11 01:16:16 +03:30
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-09-06 17:20:11 +03:00
|
|
|
fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> {
|
|
|
|
|
Err(NotSupportedError::new("set_cursor_hittest is not supported").into())
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_enabled_buttons(&self, _buttons: window::WindowButtons) {}
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn enabled_buttons(&self) -> window::WindowButtons {
|
2023-01-05 06:58:08 -07:00
|
|
|
window::WindowButtons::all()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn theme(&self) -> Option<window::Theme> {
|
2023-01-05 06:58:08 -07:00
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-17 03:30:14 +02:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn has_focus(&self) -> bool {
|
2023-01-17 03:30:14 +02:00
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
#[inline]
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_theme(&self, _theme: Option<window::Theme>) {}
|
2023-09-01 23:14:16 +02:00
|
|
|
|
2024-08-23 23:40:27 +03:00
|
|
|
fn set_content_protected(&self, _protected: bool) {}
|
|
|
|
|
|
|
|
|
|
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl rwh_06::HasWindowHandle for Window {
|
|
|
|
|
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
|
|
|
|
let raw = self.raw_window_handle_rwh_06()?;
|
|
|
|
|
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw)) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl rwh_06::HasDisplayHandle for Window {
|
|
|
|
|
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
|
|
|
|
let raw = self.raw_display_handle_rwh_06()?;
|
|
|
|
|
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for Window {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
{
|
|
|
|
|
let mut destroys = self.destroys.lock().unwrap();
|
2024-10-08 15:29:40 +02:00
|
|
|
destroys.push_back(self.id());
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2024-11-12 10:56:20 +03:00
|
|
|
self.event_loop_proxy.wake_socket.wake().unwrap();
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
}
|