linux: implement dispatcher, add dummy textsystem
This commit is contained in:
parent
d675abf70c
commit
ca62d22147
10 changed files with 194 additions and 14 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -2732,6 +2732,7 @@ checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
"nanorand",
|
||||||
"spin 0.9.8",
|
"spin 0.9.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3105,8 +3106,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3232,6 +3235,7 @@ dependencies = [
|
||||||
"dhat",
|
"dhat",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"etagere",
|
"etagere",
|
||||||
|
"flume",
|
||||||
"font-kit",
|
"font-kit",
|
||||||
"foreign-types 0.3.2",
|
"foreign-types 0.3.2",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
@ -4644,6 +4648,15 @@ dependencies = [
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nanorand"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.10",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
|
|
|
@ -94,3 +94,6 @@ log.workspace = true
|
||||||
media = { path = "../media" }
|
media = { path = "../media" }
|
||||||
metal = "0.21.0"
|
metal = "0.21.0"
|
||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
flume = "0.11"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
mod app_menu;
|
mod app_menu;
|
||||||
mod keystroke;
|
mod keystroke;
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
mod mac;
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod linux;
|
mod linux;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
mod mac;
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
|
@ -35,10 +35,10 @@ use uuid::Uuid;
|
||||||
|
|
||||||
pub use app_menu::*;
|
pub use app_menu::*;
|
||||||
pub use keystroke::*;
|
pub use keystroke::*;
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub(crate) use mac::*;
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub(crate) use linux::*;
|
pub(crate) use linux::*;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub(crate) use mac::*;
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub(crate) use test::*;
|
pub(crate) use test::*;
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
mod dispatcher;
|
||||||
mod platform;
|
mod platform;
|
||||||
|
|
||||||
|
pub(crate) use dispatcher::*;
|
||||||
pub(crate) use platform::*;
|
pub(crate) use platform::*;
|
||||||
|
|
97
crates/gpui/src/platform/linux/dispatcher.rs
Normal file
97
crates/gpui/src/platform/linux/dispatcher.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
use crate::{PlatformDispatcher, TaskLabel};
|
||||||
|
use async_task::Runnable;
|
||||||
|
use parking::{Parker, Unparker};
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use std::{
|
||||||
|
panic, thread,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) struct LinuxDispatcher {
|
||||||
|
parker: Mutex<Parker>,
|
||||||
|
timed_tasks: Mutex<Vec<(Instant, Runnable)>>,
|
||||||
|
main_sender: flume::Sender<Runnable>,
|
||||||
|
main_receiver: flume::Receiver<Runnable>,
|
||||||
|
background_sender: flume::Sender<Runnable>,
|
||||||
|
background_thread: thread::JoinHandle<()>,
|
||||||
|
main_thread_id: thread::ThreadId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LinuxDispatcher {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinuxDispatcher {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let (main_sender, main_receiver) = flume::unbounded::<Runnable>();
|
||||||
|
let (background_sender, background_receiver) = flume::unbounded::<Runnable>();
|
||||||
|
let background_thread = thread::spawn(move || {
|
||||||
|
for runnable in background_receiver {
|
||||||
|
let _ignore_panic = panic::catch_unwind(|| runnable.run());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
LinuxDispatcher {
|
||||||
|
parker: Mutex::new(Parker::new()),
|
||||||
|
timed_tasks: Mutex::new(Vec::new()),
|
||||||
|
main_sender,
|
||||||
|
main_receiver,
|
||||||
|
background_sender,
|
||||||
|
background_thread,
|
||||||
|
main_thread_id: thread::current().id(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlatformDispatcher for LinuxDispatcher {
|
||||||
|
fn is_main_thread(&self) -> bool {
|
||||||
|
thread::current().id() == self.main_thread_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch(&self, runnable: Runnable, _: Option<TaskLabel>) {
|
||||||
|
self.background_sender.send(runnable).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_on_main_thread(&self, runnable: Runnable) {
|
||||||
|
self.main_sender.send(runnable).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
|
||||||
|
let moment = Instant::now() + duration;
|
||||||
|
let mut timed_tasks = self.timed_tasks.lock();
|
||||||
|
timed_tasks.push((moment, runnable));
|
||||||
|
timed_tasks.sort_unstable_by(|&(ref a, _), &(ref b, _)| b.cmp(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tick(&self, background_only: bool) -> bool {
|
||||||
|
let mut ran = false;
|
||||||
|
if self.is_main_thread() && !background_only {
|
||||||
|
for runnable in self.main_receiver.try_iter() {
|
||||||
|
runnable.run();
|
||||||
|
ran = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut timed_tasks = self.timed_tasks.lock();
|
||||||
|
while let Some(&(moment, _)) = timed_tasks.last() {
|
||||||
|
if moment <= Instant::now() {
|
||||||
|
let (_, runnable) = timed_tasks.pop().unwrap();
|
||||||
|
runnable.run();
|
||||||
|
ran = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ran
|
||||||
|
}
|
||||||
|
|
||||||
|
fn park(&self) {
|
||||||
|
self.parker.lock().park()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparker(&self) -> Unparker {
|
||||||
|
self.parker.lock().unparker()
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId,
|
Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId,
|
||||||
Keymap, Menu, PathPromptOptions, Platform, PlatformDisplay, PlatformInput,
|
ForegroundExecutor, Keymap, LinuxDispatcher, Menu, PathPromptOptions, Platform,
|
||||||
PlatformTextSystem, PlatformWindow, Result, SemanticVersion, Task, WindowOptions,
|
PlatformDisplay, PlatformInput, PlatformTextSystem, PlatformWindow, Result, SemanticVersion,
|
||||||
|
Task, WindowOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
|
@ -17,10 +18,11 @@ use std::{
|
||||||
};
|
};
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
|
||||||
|
|
||||||
pub(crate) struct LinuxPlatform(Mutex<LinuxPlatformState>);
|
pub(crate) struct LinuxPlatform(Mutex<LinuxPlatformState>);
|
||||||
|
|
||||||
pub(crate) struct LinuxPlatformState {
|
pub(crate) struct LinuxPlatformState {
|
||||||
|
background_executor: BackgroundExecutor,
|
||||||
|
foreground_executor: ForegroundExecutor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LinuxPlatform {
|
impl Default for LinuxPlatform {
|
||||||
|
@ -31,18 +33,21 @@ impl Default for LinuxPlatform {
|
||||||
|
|
||||||
impl LinuxPlatform {
|
impl LinuxPlatform {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
|
let dispatcher = Arc::new(LinuxDispatcher::new());
|
||||||
Self(Mutex::new(LinuxPlatformState {
|
Self(Mutex::new(LinuxPlatformState {
|
||||||
|
background_executor: BackgroundExecutor::new(dispatcher.clone()),
|
||||||
|
foreground_executor: ForegroundExecutor::new(dispatcher),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform for LinuxPlatform {
|
impl Platform for LinuxPlatform {
|
||||||
fn background_executor(&self) -> BackgroundExecutor {
|
fn background_executor(&self) -> BackgroundExecutor {
|
||||||
unimplemented!()
|
self.0.lock().background_executor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foreground_executor(&self) -> crate::ForegroundExecutor {
|
fn foreground_executor(&self) -> crate::ForegroundExecutor {
|
||||||
unimplemented!()
|
self.0.lock().foreground_executor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
mod dispatcher;
|
mod dispatcher;
|
||||||
mod display;
|
mod display;
|
||||||
mod platform;
|
mod platform;
|
||||||
|
mod text_system;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
pub(crate) use dispatcher::*;
|
pub(crate) use dispatcher::*;
|
||||||
pub(crate) use display::*;
|
pub(crate) use display::*;
|
||||||
pub(crate) use platform::*;
|
pub(crate) use platform::*;
|
||||||
|
pub(crate) use text_system::*;
|
||||||
pub(crate) use window::*;
|
pub(crate) use window::*;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor,
|
AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor,
|
||||||
Keymap, Platform, PlatformDisplay, PlatformTextSystem, Task, TestDisplay, TestWindow,
|
Keymap, Platform, PlatformDisplay, PlatformTextSystem, Task, TestDisplay, TestTextSystem,
|
||||||
WindowOptions,
|
TestWindow, WindowOptions,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use collections::VecDeque;
|
use collections::VecDeque;
|
||||||
|
@ -118,7 +118,7 @@ impl Platform for TestPlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
||||||
Arc::new(crate::platform::mac::MacTextSystem::new())
|
Arc::new(TestTextSystem {})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _on_finish_launching: Box<dyn FnOnce()>) {
|
fn run(&self, _on_finish_launching: Box<dyn FnOnce()>) {
|
||||||
|
|
58
crates/gpui/src/platform/test/text_system.rs
Normal file
58
crates/gpui/src/platform/test/text_system.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use crate::{
|
||||||
|
Bounds, DevicePixels, Font, FontId, FontMetrics, FontRun, GlyphId, LineLayout, Pixels,
|
||||||
|
PlatformTextSystem, RenderGlyphParams, Size,
|
||||||
|
};
|
||||||
|
use anyhow::Result;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub(crate) struct TestTextSystem {}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
impl PlatformTextSystem for TestTextSystem {
|
||||||
|
fn add_fonts(&self, fonts: &[Arc<Vec<u8>>]) -> Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn all_font_names(&self) -> Vec<String> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn all_font_families(&self) -> Vec<String> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn font_id(&self, descriptor: &Font) -> Result<FontId> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn font_metrics(&self, font_id: FontId) -> FontMetrics {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Bounds<f32>> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn advance(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Size<f32>> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option<GlyphId> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn rasterize_glyph(
|
||||||
|
&self,
|
||||||
|
params: &RenderGlyphParams,
|
||||||
|
raster_bounds: Bounds<DevicePixels>,
|
||||||
|
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn layout_line(&self, text: &str, font_size: Pixels, runs: &[FontRun]) -> LineLayout {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn wrap_line(
|
||||||
|
&self,
|
||||||
|
text: &str,
|
||||||
|
font_id: FontId,
|
||||||
|
font_size: Pixels,
|
||||||
|
width: Pixels,
|
||||||
|
) -> Vec<usize> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,8 +35,8 @@ use crate::{
|
||||||
InputHandler, IsZero, KeyContext, KeyEvent, KeymatchMode, LayoutId, MonochromeSprite,
|
InputHandler, IsZero, KeyContext, KeyEvent, KeymatchMode, LayoutId, MonochromeSprite,
|
||||||
MouseEvent, PaintQuad, Path, Pixels, PlatformInputHandler, Point, PolychromeSprite, Quad,
|
MouseEvent, PaintQuad, Path, Pixels, PlatformInputHandler, Point, PolychromeSprite, Quad,
|
||||||
RenderGlyphParams, RenderImageParams, RenderSvgParams, Scene, Shadow, SharedString, Size,
|
RenderGlyphParams, RenderImageParams, RenderSvgParams, Scene, Shadow, SharedString, Size,
|
||||||
StackingContext, StackingOrder, Style, TextStyleRefinement, Underline, UnderlineStyle,
|
StackingContext, StackingOrder, Style, TextStyleRefinement, Underline, UnderlineStyle, Window,
|
||||||
Window, WindowContext, SUBPIXEL_VARIANTS,
|
WindowContext, SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
|
|
||||||
type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut ElementContext) + 'static>;
|
type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut ElementContext) + 'static>;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue