diff --git a/druid-shell/Cargo.toml b/druid-shell/Cargo.toml index e8c066cb6f..0a24fc8551 100755 --- a/druid-shell/Cargo.toml +++ b/druid-shell/Cargo.toml @@ -39,31 +39,47 @@ wayland = [ "bindgen", "pkg-config", ] -# Implement HasRawWindowHandle for WindowHandle -raw-win-handle = ["raw-window-handle"] # passing on all the image features. AVIF is not supported because it does not # support decoding, and that's all we use `Image` for. -image_png = ["piet-common/image_png"] -jpeg = ["piet-common/jpeg"] -jpeg_rayon = ["piet-common/jpeg_rayon"] -gif = ["piet-common/gif"] -bmp = ["piet-common/bmp"] -ico = ["piet-common/ico"] -tiff = ["piet-common/tiff"] -webp = ["piet-common/webp"] -pnm = ["piet-common/pnm"] -dds = ["piet-common/dds"] -tga = ["piet-common/tga"] -farbfeld = ["piet-common/farbfeld"] -dxt = ["piet-common/dxt"] -hdr = ["piet-common/hdr"] +# image_png = ["piet-common/image_png"] +# jpeg = ["piet-common/jpeg"] +# jpeg_rayon = ["piet-common/jpeg_rayon"] +# gif = ["piet-common/gif"] +# bmp = ["piet-common/bmp"] +# ico = ["piet-common/ico"] +# tiff = ["piet-common/tiff"] +# webp = ["piet-common/webp"] +# pnm = ["piet-common/pnm"] +# dds = ["piet-common/dds"] +# tga = ["piet-common/tga"] +# farbfeld = ["piet-common/farbfeld"] +# dxt = ["piet-common/dxt"] +# hdr = ["piet-common/hdr"] +bmp = [] +dds = [] +dxt = [] +farbfeld = [] +gif = [] +jpeg = [] +png = [] +ico = [] +tiff = [] +webp = [] +tga = [] +hdr = [] +image_png = [] +jpeg_rayon = [] +pnm = [] + + + serde = ["kurbo/serde"] [dependencies] # NOTE: When changing the piet or kurbo versions, ensure that # the kurbo version included in piet is compatible with the kurbo version specified here. -piet-common = "=0.5.0" +# piet-common = "=0.5.0" kurbo = "0.8.2" tracing = "0.1.22" @@ -76,7 +92,7 @@ keyboard-types = { version = "0.6.2", default_features = false } # Optional dependencies image = { version = "0.23.12", optional = true, default_features = false } -raw-window-handle = { version = "0.4.2", optional = true, default_features = false } +raw-window-handle = { version = "0.4.2", default_features = false } [target.'cfg(target_os="windows")'.dependencies] scopeguard = "1.1.0" @@ -132,6 +148,7 @@ static_assertions = "1.1.0" test-log = { version = "0.2.5", features = ["trace"], default-features = false } tracing-subscriber = { version = "0.3.2", features = ["env-filter"] } unicode-segmentation = "1.7.0" +piet-gpu-hal = { git = "https://github.com/linebender/piet-gpu", rev = "947a85f" } [build-dependencies] bindgen = {version = "0.58", optional = true} diff --git a/druid-shell/examples/gpu.rs b/druid-shell/examples/gpu.rs new file mode 100644 index 0000000000..f0527f976f --- /dev/null +++ b/druid-shell/examples/gpu.rs @@ -0,0 +1,370 @@ +// Copyright 2018 The Druid Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::any::Any; +use std::sync::{Arc, Mutex}; + +use druid_shell::kurbo::Size; + +use druid_shell::{ + Application, Cursor, FileDialogOptions, FileDialogToken, FileInfo, FileSpec, HotKey, KeyEvent, + Menu, MouseEvent, Region, SysMods, TimerToken, WinHandler, WindowBuilder, WindowHandle, +}; +use piet_gpu_hal::{ + include_shader, BindType, Buffer, BufferUsage, ComputePassDescriptor, DescriptorSet, Image, + ImageFormat, ImageLayout, Instance, InstanceFlags, Pipeline, Semaphore, Session, Swapchain, +}; + +#[derive(Default)] +struct HelloState { + size: Size, + handle: WindowHandle, + gpu_state: Arc>>, +} + +impl WinHandler for HelloState { + fn connect(&mut self, handle: &WindowHandle) { + self.handle = handle.clone(); + } + + fn prepare_paint(&mut self) { + self.handle.invalidate(); + } + + fn paint(&mut self, _: &Region) { + unsafe { + // TODO: wire up size + let width = 1000; + let height = 800; + let mut state_guard = self.gpu_state.lock().unwrap(); + let state = state_guard.as_mut().unwrap(); + let frame_idx = state.current_frame % 2; + let (image_idx, acquisition_semaphore) = state.swapchain.next().unwrap(); + let swap_image = state.swapchain.image(image_idx); + + // TODO: wire up time for animation purposes + let i_time: f32 = 0.0; + let config_data = [width, height, i_time.to_bits()]; + state.config_host.write(&config_data).unwrap(); + + let mut cmd_buf = state.session.cmd_buf().unwrap(); + cmd_buf.begin(); + cmd_buf.image_barrier(&swap_image, ImageLayout::Undefined, ImageLayout::BlitDst); + cmd_buf.copy_buffer(&state.config_host, &state.config_dev); + cmd_buf.memory_barrier(); + + cmd_buf.image_barrier( + &state.staging_img, + ImageLayout::Undefined, + ImageLayout::General, + ); + let wg_x = width / 16; + let wg_y = height / 16; + let mut pass = cmd_buf.begin_compute_pass(&ComputePassDescriptor::default()); + pass.dispatch( + &state.pipeline, + &state.descriptor_set, + (wg_x, wg_y, 1), + (16, 16, 1), + ); + pass.end(); + cmd_buf.image_barrier( + &state.staging_img, + ImageLayout::General, + ImageLayout::BlitSrc, + ); + cmd_buf.blit_image(&state.staging_img, &swap_image); + cmd_buf.image_barrier(&swap_image, ImageLayout::BlitDst, ImageLayout::Present); + cmd_buf.finish(); + let submitted = state + .session + .run_cmd_buf( + cmd_buf, + &[&acquisition_semaphore], + &[&state.present_semaphores[frame_idx]], + ) + .unwrap(); + state + .swapchain + .present(image_idx, &[&state.present_semaphores[frame_idx]]) + .unwrap(); + let start = std::time::Instant::now(); + submitted.wait().unwrap(); + println!("wait elapsed: {:?}", start.elapsed()); + state.current_frame += 1; + } + } + + fn command(&mut self, id: u32) { + match id { + 0x100 => { + self.handle.close(); + Application::global().quit() + } + 0x101 => { + let options = FileDialogOptions::new().show_hidden().allowed_types(vec![ + FileSpec::new("Rust Files", &["rs", "toml"]), + FileSpec::TEXT, + FileSpec::JPG, + ]); + self.handle.open_file(options); + } + 0x102 => { + let options = FileDialogOptions::new().show_hidden().allowed_types(vec![ + FileSpec::new("Rust Files", &["rs", "toml"]), + FileSpec::TEXT, + FileSpec::JPG, + ]); + self.handle.save_as(options); + } + _ => println!("unexpected id {}", id), + } + } + + fn open_file(&mut self, _token: FileDialogToken, file_info: Option) { + println!("open file result: {:?}", file_info); + } + + fn save_as(&mut self, _token: FileDialogToken, file: Option) { + println!("save file result: {:?}", file); + } + + fn key_down(&mut self, event: KeyEvent) -> bool { + println!("keydown: {:?}", event); + false + } + + fn key_up(&mut self, event: KeyEvent) { + println!("keyup: {:?}", event); + } + + fn wheel(&mut self, event: &MouseEvent) { + println!("mouse_wheel {:?}", event); + } + + fn mouse_move(&mut self, event: &MouseEvent) { + self.handle.set_cursor(&Cursor::Arrow); + println!("mouse_move {:?}", event); + } + + fn mouse_down(&mut self, event: &MouseEvent) { + println!("mouse_down {:?}", event); + self.render(); + } + + fn mouse_up(&mut self, event: &MouseEvent) { + println!("mouse_up {:?}", event); + } + + fn timer(&mut self, id: TimerToken) { + println!("timer fired: {:?}", id); + } + + fn size(&mut self, size: Size) { + println!("size: {:?}", size); + self.size = size; + } + + fn got_focus(&mut self) { + println!("Got focus"); + } + + fn lost_focus(&mut self) { + println!("Lost focus"); + } + + fn request_close(&mut self) { + self.handle.close(); + } + + fn destroy(&mut self) { + Application::global().quit() + } + + fn as_any(&mut self) -> &mut dyn Any { + self + } +} + +impl HelloState { + fn render(&self) { + unsafe { + // TODO: wire up size + let width = 1000; + let height = 800; + let mut state_guard = self.gpu_state.lock().unwrap(); + let state = state_guard.as_mut().unwrap(); + let frame_idx = state.current_frame % 2; + let (image_idx, acquisition_semaphore) = state.swapchain.next().unwrap(); + let swap_image = state.swapchain.image(image_idx); + + // TODO: wire up time for animation purposes + let i_time: f32 = 0.0; + let config_data = [width, height, i_time.to_bits()]; + state.config_host.write(&config_data).unwrap(); + + let mut cmd_buf = state.session.cmd_buf().unwrap(); + cmd_buf.begin(); + cmd_buf.image_barrier(&swap_image, ImageLayout::Undefined, ImageLayout::BlitDst); + cmd_buf.copy_buffer(&state.config_host, &state.config_dev); + cmd_buf.memory_barrier(); + + cmd_buf.image_barrier( + &state.staging_img, + ImageLayout::Undefined, + ImageLayout::General, + ); + let wg_x = width / 16; + let wg_y = height / 16; + let mut pass = cmd_buf.begin_compute_pass(&ComputePassDescriptor::default()); + pass.dispatch( + &state.pipeline, + &state.descriptor_set, + (wg_x, wg_y, 1), + (16, 16, 1), + ); + pass.end(); + cmd_buf.image_barrier( + &state.staging_img, + ImageLayout::General, + ImageLayout::BlitSrc, + ); + cmd_buf.blit_image(&state.staging_img, &swap_image); + cmd_buf.image_barrier(&swap_image, ImageLayout::BlitDst, ImageLayout::Present); + cmd_buf.finish(); + let submitted = state + .session + .run_cmd_buf( + cmd_buf, + &[&acquisition_semaphore], + &[&state.present_semaphores[frame_idx]], + ) + .unwrap(); + state + .swapchain + .present(image_idx, &[&state.present_semaphores[frame_idx]]) + .unwrap(); + let start = std::time::Instant::now(); + submitted.wait().unwrap(); + println!("wait elapsed: {:?}", start.elapsed()); + state.current_frame += 1; + } + } +} + +fn main() { + tracing_subscriber::fmt().init(); + let mut file_menu = Menu::new(); + file_menu.add_item( + 0x100, + "E&xit", + Some(&HotKey::new(SysMods::Cmd, "q")), + true, + false, + ); + file_menu.add_item( + 0x101, + "O&pen", + Some(&HotKey::new(SysMods::Cmd, "o")), + true, + false, + ); + file_menu.add_item( + 0x102, + "S&ave", + Some(&HotKey::new(SysMods::Cmd, "s")), + true, + false, + ); + let mut menubar = Menu::new(); + menubar.add_dropdown(Menu::new(), "Application", true); + menubar.add_dropdown(file_menu, "&File", true); + + let app = Application::new().unwrap(); + let mut builder = WindowBuilder::new(app.clone()); + let win_state = HelloState::default(); + let gpu_state = win_state.gpu_state.clone(); + builder.set_handler(Box::new(win_state)); + builder.set_title("Hello example"); + builder.set_menu(menubar); + + let window = builder.build().unwrap(); + unsafe { + let width = 1000; + let height = 800; + let state = GpuState::new(&window, width, height).unwrap(); + *gpu_state.lock().unwrap() = Some(state); + } + window.show(); + + app.run(None); +} + +struct GpuState { + current_frame: usize, + instance: Instance, + session: Session, + swapchain: Swapchain, + present_semaphores: Vec, + pipeline: Pipeline, + descriptor_set: DescriptorSet, + config_host: Buffer, + config_dev: Buffer, + staging_img: Image, +} + +impl GpuState { + unsafe fn new( + window: &WindowHandle, + width: usize, + height: usize, + ) -> Result> { + let instance = Instance::new(InstanceFlags::empty())?; + let surface = instance.surface(&window)?; + let device = instance.device()?; + let swapchain = instance.swapchain(width, height, &device, &surface)?; + let session = Session::new(device); + let present_semaphores = (0..2) + .map(|_| session.create_semaphore()) + .collect::, _>>()?; + let shader_code = include_shader!(&session, "../shader/gen/shader"); + let pipeline = + session.create_compute_pipeline(shader_code, &[BindType::Buffer, BindType::Image])?; + let config_size = 12; + let config_host = + session.create_buffer(config_size, BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE)?; + let config_dev = + session.create_buffer(config_size, BufferUsage::COPY_DST | BufferUsage::STORAGE)?; + let staging_img = + session.create_image2d(width as u32, height as u32, ImageFormat::Rgba8)?; + let descriptor_set = session + .descriptor_set_builder() + .add_buffers(&[&config_dev]) + .add_images(&[&staging_img]) + .build(&session, &pipeline)?; + let current_frame = 0; + Ok(GpuState { + current_frame, + instance, + session, + swapchain, + present_semaphores, + pipeline, + descriptor_set, + config_host, + config_dev, + staging_img, + }) + } +} diff --git a/druid-shell/shader/build.ninja b/druid-shell/shader/build.ninja new file mode 100644 index 0000000000..d22b6da2e7 --- /dev/null +++ b/druid-shell/shader/build.ninja @@ -0,0 +1,19 @@ +# Build file for shaders. + +# You must have Vulkan tools in your path, or patch here. + +glslang_validator = glslangValidator +spirv_cross = spirv-cross + +rule glsl + command = $glslang_validator -V -o $out $in + +rule hlsl + command = $spirv_cross --hlsl --shader-model 50 $in --output $out + +rule msl + command = $spirv_cross --msl $in --output $out + +build gen/shader.spv: glsl shader.comp +build gen/shader.hlsl: hlsl gen/shader.spv +build gen/shader.msl: msl gen/shader.spv diff --git a/druid-shell/shader/gen/shader.dxil b/druid-shell/shader/gen/shader.dxil new file mode 100644 index 0000000000..e69de29bb2 diff --git a/druid-shell/shader/gen/shader.hlsl b/druid-shell/shader/gen/shader.hlsl new file mode 100644 index 0000000000..503b30c557 --- /dev/null +++ b/druid-shell/shader/gen/shader.hlsl @@ -0,0 +1,25 @@ +static const uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); + +RWByteAddressBuffer _24 : register(u0); +RWTexture2D image : register(u1); + +static uint3 gl_GlobalInvocationID; +struct SPIRV_Cross_Input +{ + uint3 gl_GlobalInvocationID : SV_DispatchThreadID; +}; + +void comp_main() +{ + uint2 xy = gl_GlobalInvocationID.xy; + float2 fragCoord = (float2(gl_GlobalInvocationID.xy) / float2(float(_24.Load(0)), float(_24.Load(4)))) - 0.5f.xx; + float4 fragColor = float4(fragCoord.x + 0.5f, fragCoord.y + 0.5f, 0.5f + (0.5f * sin(asfloat(_24.Load(8)))), 1.0f); + image[int2(xy)] = fragColor; +} + +[numthreads(16, 16, 1)] +void main(SPIRV_Cross_Input stage_input) +{ + gl_GlobalInvocationID = stage_input.gl_GlobalInvocationID; + comp_main(); +} diff --git a/druid-shell/shader/gen/shader.msl b/druid-shell/shader/gen/shader.msl new file mode 100644 index 0000000000..e34a579b98 --- /dev/null +++ b/druid-shell/shader/gen/shader.msl @@ -0,0 +1,22 @@ +#include +#include + +using namespace metal; + +struct Params +{ + uint width; + uint height; + float iTime; +}; + +constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(16u, 16u, 1u); + +kernel void main0(device Params& _24 [[buffer(0)]], texture2d image [[texture(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) +{ + uint2 xy = gl_GlobalInvocationID.xy; + float2 fragCoord = (float2(gl_GlobalInvocationID.xy) / float2(float(_24.width), float(_24.height))) - float2(0.5); + float4 fragColor = float4(fragCoord.x + 0.5, fragCoord.y + 0.5, 0.5 + (0.5 * sin(_24.iTime)), 1.0); + image.write(fragColor, uint2(int2(xy))); +} + diff --git a/druid-shell/shader/gen/shader.spv b/druid-shell/shader/gen/shader.spv new file mode 100644 index 0000000000..3e02018ac1 Binary files /dev/null and b/druid-shell/shader/gen/shader.spv differ diff --git a/druid-shell/shader/shader.comp b/druid-shell/shader/shader.comp new file mode 100644 index 0000000000..349dbd6138 --- /dev/null +++ b/druid-shell/shader/shader.comp @@ -0,0 +1,39 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Also licensed under MIT license, at your choice. + +// Simple compute shader for generating an image +// When updating, remember to recompile using ninja. + +#version 450 +layout(local_size_x = 16, local_size_y = 16) in; + +layout(set = 0, binding = 0) restrict buffer Params { + uint width; + uint height; + float iTime; +}; + +layout(rgba8, set = 0, binding = 1) uniform restrict writeonly image2D image; + +void main() { + uvec2 xy = gl_GlobalInvocationID.xy; + vec2 fragCoord = vec2(gl_GlobalInvocationID.xy) / vec2(float(width), float(height)) - 0.5; + + // Shadertoy-like code can go here. + vec4 fragColor = vec4(fragCoord.x + 0.5, fragCoord.y + 0.5, 0.5 + 0.5 * sin(iTime), 1.0); + + imageStore(image, ivec2(xy), fragColor); +} diff --git a/druid-shell/src/backend/gtk/window.rs b/druid-shell/src/backend/gtk/window.rs index 0d08f782fb..ce3a02323c 100644 --- a/druid-shell/src/backend/gtk/window.rs +++ b/druid-shell/src/backend/gtk/window.rs @@ -43,7 +43,6 @@ use gtk::gdk::{ use instant::Duration; use tracing::{error, warn}; -#[cfg(feature = "raw-win-handle")] use raw_window_handle::{unix::XcbHandle, HasRawWindowHandle, RawWindowHandle}; use crate::kurbo::{Insets, Point, Rect, Size, Vec2}; @@ -121,7 +120,6 @@ impl PartialEq for WindowHandle { } impl Eq for WindowHandle {} -#[cfg(feature = "raw-win-handle")] unsafe impl HasRawWindowHandle for WindowHandle { fn raw_window_handle(&self) -> RawWindowHandle { error!("HasRawWindowHandle trait not implemented for gtk."); diff --git a/druid-shell/src/backend/mac/text_input.rs b/druid-shell/src/backend/mac/text_input.rs index 766914e662..a14cbd106f 100644 --- a/druid-shell/src/backend/mac/text_input.rs +++ b/druid-shell/src/backend/mac/text_input.rs @@ -217,11 +217,13 @@ pub extern "C" fn character_index_for_point( _: Sel, point: NSPoint, ) -> NSUInteger { - with_edit_lock_from_window(this, true, |edit_lock| { - let hit_test = edit_lock.hit_test_point(Point::new(point.x, point.y)); - hit_test.idx as NSUInteger - }) - .unwrap_or(0) + // TODO: figure out how to do text hit testing without piet + // with_edit_lock_from_window(this, true, |edit_lock| { + // let hit_test = edit_lock.hit_test_point(Point::new(point.x, point.y)); + // hit_test.idx as NSUInteger + // }) + // .unwrap_or(0) + 0 } pub extern "C" fn first_rect_for_character_range( diff --git a/druid-shell/src/backend/mac/window.rs b/druid-shell/src/backend/mac/window.rs index a212412cf3..d7263ce828 100644 --- a/druid-shell/src/backend/mac/window.rs +++ b/druid-shell/src/backend/mac/window.rs @@ -39,11 +39,9 @@ use objc::runtime::{Class, Object, Protocol, Sel}; use objc::{class, msg_send, sel, sel_impl}; use tracing::{debug, error, info}; -#[cfg(feature = "raw-win-handle")] -use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{AppKitHandle, HasRawWindowHandle, RawWindowHandle}; use crate::kurbo::{Insets, Point, Rect, Size, Vec2}; -use crate::piet::{Piet, PietText, RenderContext}; use super::appkit::{ NSRunLoopCommonModes, NSTrackingArea, NSTrackingAreaOptions, NSView as NSViewExt, @@ -175,7 +173,6 @@ struct ViewState { // Tracks whether we have already received the mouseExited event mouse_left: bool, keyboard_state: KeyboardState, - text: PietText, active_text_input: Option, parent: Option, } @@ -556,7 +553,6 @@ fn make_view(handler: Box) -> (id, Weak>>) { focus_click: false, mouse_left: true, keyboard_state, - text: PietText::new_with_unique_state(), active_text_input: None, parent: None, }; @@ -848,13 +844,6 @@ extern "C" fn view_will_draw(this: &mut Object, _: Sel) { extern "C" fn draw_rect(this: &mut Object, _: Sel, dirtyRect: NSRect) { unsafe { - let context: id = msg_send![class![NSGraphicsContext], currentContext]; - //FIXME: when core_graphics is at 0.20, we should be able to use - //core_graphics::sys::CGContextRef as our pointer type. - let cgcontext_ptr: *mut ::CType = - msg_send![context, CGContext]; - let cgcontext_ref = CGContextRef::from_ptr_mut(cgcontext_ptr); - // FIXME: use the actual invalid region instead of just this bounding box. // https://developer.apple.com/documentation/appkit/nsview/1483772-getrectsbeingdrawn?language=objc let rect = Rect::from_origin_size( @@ -865,12 +854,8 @@ extern "C" fn draw_rect(this: &mut Object, _: Sel, dirtyRect: NSRect) { let view_state: *mut c_void = *this.get_ivar("viewState"); let view_state = &mut *(view_state as *mut ViewState); - let mut piet_ctx = Piet::new_y_down(cgcontext_ref, Some(view_state.text.clone())); - (*view_state).handler.paint(&mut piet_ctx, &invalid); - if let Err(e) = piet_ctx.finish() { - error!("{}", e) - } + (*view_state).handler.paint(&invalid); let superclass = msg_send![this, superclass]; let () = msg_send![super(this, superclass), drawRect: dirtyRect]; @@ -1106,19 +1091,6 @@ impl WindowHandle { token } - pub fn text(&self) -> PietText { - let view = self.nsview.load(); - unsafe { - if let Some(view) = (*view).as_ref() { - let state: *mut c_void = *view.get_ivar("viewState"); - (*(state as *mut ViewState)).text.clone() - } else { - // this codepath should only happen during tests in druid, when view is nil - PietText::new_with_unique_state() - } - } - } - pub fn add_text_field(&self) -> TextFieldToken { TextFieldToken::next() } @@ -1411,15 +1383,12 @@ impl WindowHandle { } } -#[cfg(feature = "raw-win-handle")] unsafe impl HasRawWindowHandle for WindowHandle { fn raw_window_handle(&self) -> RawWindowHandle { + let mut handle = AppKitHandle::empty(); let nsv = self.nsview.load(); - let handle = MacOSHandle { - ns_view: *nsv as *mut _, - ..MacOSHandle::empty() - }; - RawWindowHandle::MacOS(handle) + handle.ns_view = *nsv as *mut _; + RawWindowHandle::AppKit(handle) } } diff --git a/druid-shell/src/backend/web/window.rs b/druid-shell/src/backend/web/window.rs index 4dfd1ddfc1..369544f5aa 100644 --- a/druid-shell/src/backend/web/window.rs +++ b/druid-shell/src/backend/web/window.rs @@ -24,7 +24,6 @@ use tracing::{error, warn}; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; -#[cfg(feature = "raw-win-handle")] use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; use crate::kurbo::{Insets, Point, Rect, Size, Vec2}; @@ -90,7 +89,6 @@ impl PartialEq for WindowHandle { } impl Eq for WindowHandle {} -#[cfg(feature = "raw-win-handle")] unsafe impl HasRawWindowHandle for WindowHandle { fn raw_window_handle(&self) -> RawWindowHandle { error!("HasRawWindowHandle trait not implemented for wasm."); diff --git a/druid-shell/src/backend/windows/application.rs b/druid-shell/src/backend/windows/application.rs index 084757b5f6..5ca9e4b045 100644 --- a/druid-shell/src/backend/windows/application.rs +++ b/druid-shell/src/backend/windows/application.rs @@ -35,8 +35,6 @@ use winapi::um::winuser::{ IDI_APPLICATION, MSG, PM_NOREMOVE, WM_TIMER, WNDCLASSW, }; -use piet_common::D2DLoadedFonts; - use crate::application::AppHandler; use super::accels; @@ -48,7 +46,6 @@ use super::window::{self, DS_REQUEST_DESTROY}; #[derive(Clone)] pub(crate) struct Application { state: Rc>, - pub(crate) fonts: D2DLoadedFonts, } struct State { @@ -66,8 +63,7 @@ impl Application { quitting: false, windows: HashSet::new(), })); - let fonts = D2DLoadedFonts::default(); - Ok(Application { state, fonts }) + Ok(Application { state }) } /// Initialize the app. At the moment, this is mostly needed for hi-dpi. diff --git a/druid-shell/src/backend/windows/mod.rs b/druid-shell/src/backend/windows/mod.rs index 7d77da681d..9204fe699f 100644 --- a/druid-shell/src/backend/windows/mod.rs +++ b/druid-shell/src/backend/windows/mod.rs @@ -17,12 +17,12 @@ mod accels; pub mod application; pub mod clipboard; -pub mod dcomp; +// pub mod dcomp; pub mod dialog; pub mod error; mod keyboard; pub mod menu; -pub mod paint; +// pub mod paint; pub mod screen; mod timers; pub mod util; @@ -46,40 +46,11 @@ pub mod window; // Basically, go from HwndRenderTarget or DxgiSurfaceRenderTarget (2d or 3d) to a Device Context. // Go back up for particular needs. -use piet_common::d2d::DeviceContext; use std::fmt::{Debug, Display, Formatter}; use winapi::shared::winerror::HRESULT; use winapi::um::d2d1::ID2D1RenderTarget; use wio::com::ComPtr; -#[derive(Clone)] -pub struct DxgiSurfaceRenderTarget { - ptr: ComPtr, -} - -impl DxgiSurfaceRenderTarget { - /// construct from raw ptr - /// - /// # Safety - /// TODO - pub unsafe fn from_raw(raw: *mut ID2D1RenderTarget) -> Self { - DxgiSurfaceRenderTarget { - ptr: ComPtr::from_raw(raw), - } - } - - /// cast to DeviceContext - /// - /// # Safety - /// TODO - pub unsafe fn as_device_context(&self) -> Option { - self.ptr - .cast() - .ok() - .map(|com_ptr| DeviceContext::new(com_ptr)) - } -} - // error handling pub enum Error { WinapiError(HRESULT), diff --git a/druid-shell/src/backend/windows/paint.rs b/druid-shell/src/backend/windows/paint.rs index 56298cf5ba..e9499f61c5 100644 --- a/druid-shell/src/backend/windows/paint.rs +++ b/druid-shell/src/backend/windows/paint.rs @@ -30,54 +30,8 @@ use winapi::um::d2d1::*; use winapi::um::dcommon::*; use winapi::Interface; -use piet_common::d2d::D2DFactory; - -use crate::backend::windows::DxgiSurfaceRenderTarget; use crate::scale::Scale; use super::error::Error; use super::util::as_result; use super::window::SCALE_TARGET_DPI; - -/// Create a render target from a DXGI swapchain. -/// -/// TODO: probably want to create a DeviceContext, it's more flexible. -pub(crate) unsafe fn create_render_target_dxgi( - d2d_factory: &D2DFactory, - swap_chain: *mut IDXGISwapChain1, - scale: Scale, - transparent: bool, -) -> Result { - let mut buffer: *mut IDXGISurface = null_mut(); - as_result((*swap_chain).GetBuffer( - 0, - &IDXGISurface::uuidof(), - &mut buffer as *mut _ as *mut *mut c_void, - ))?; - let props = D2D1_RENDER_TARGET_PROPERTIES { - _type: D2D1_RENDER_TARGET_TYPE_DEFAULT, - pixelFormat: D2D1_PIXEL_FORMAT { - format: DXGI_FORMAT_B8G8R8A8_UNORM, - alphaMode: if transparent { - D2D1_ALPHA_MODE_PREMULTIPLIED - } else { - D2D1_ALPHA_MODE_IGNORE - }, - }, - dpiX: (scale.x() * SCALE_TARGET_DPI) as f32, - dpiY: (scale.y() * SCALE_TARGET_DPI) as f32, - usage: D2D1_RENDER_TARGET_USAGE_NONE, - minLevel: D2D1_FEATURE_LEVEL_DEFAULT, - }; - - let mut render_target: *mut ID2D1RenderTarget = null_mut(); - let res = - (*d2d_factory.get_raw()).CreateDxgiSurfaceRenderTarget(buffer, &props, &mut render_target); - (*buffer).Release(); - if SUCCEEDED(res) { - // TODO: maybe use builder - Ok(DxgiSurfaceRenderTarget::from_raw(render_target)) - } else { - Err(res.into()) - } -} diff --git a/druid-shell/src/backend/windows/window.rs b/druid-shell/src/backend/windows/window.rs index 04597dd5ff..3e2ea05130 100644 --- a/druid-shell/src/backend/windows/window.rs +++ b/druid-shell/src/backend/windows/window.rs @@ -46,23 +46,16 @@ use winapi::um::winuser::*; use winapi::Interface; use wio::com::ComPtr; -#[cfg(feature = "raw-win-handle")] -use raw_window_handle::{windows::WindowsHandle, HasRawWindowHandle, RawWindowHandle}; - -use piet_common::d2d::{D2DFactory, DeviceContext}; -use piet_common::dwrite::DwriteFactory; +use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, Win32Handle}; use crate::kurbo::{Insets, Point, Rect, Size, Vec2}; -use crate::piet::{Piet, PietText, RenderContext}; use super::accels::register_accel; use super::application::Application; -use super::dcomp::D3D11Device; use super::dialog::get_file_dialog_path; use super::error::Error; use super::keyboard::{self, KeyboardState}; use super::menu::Menu; -use super::paint; use super::timers::TimerSlots; use super::util::{self, as_result, FromWide, ToWide, OPTIONAL_FUNCTIONS}; @@ -165,7 +158,6 @@ enum DeferredOp { #[derive(Clone, Debug)] pub struct WindowHandle { - text: PietText, state: Weak, } @@ -180,23 +172,17 @@ impl PartialEq for WindowHandle { } impl Eq for WindowHandle {} -#[cfg(feature = "raw-win-handle")] unsafe impl HasRawWindowHandle for WindowHandle { fn raw_window_handle(&self) -> RawWindowHandle { + let mut handle = Win32Handle::empty(); if let Some(hwnd) = self.get_hwnd() { - let handle = WindowsHandle { - hwnd: hwnd as *mut core::ffi::c_void, - hinstance: unsafe { - winapi::um::libloaderapi::GetModuleHandleW(0 as winapi::um::winnt::LPCWSTR) - as *mut core::ffi::c_void - }, - ..WindowsHandle::empty() + handle.hwnd = hwnd as *mut core::ffi::c_void; + handle.hinstance = unsafe { + winapi::um::libloaderapi::GetModuleHandleW(0 as winapi::um::winnt::LPCWSTR) + as *mut core::ffi::c_void }; - RawWindowHandle::Windows(handle) - } else { - error!("Cannot retrieved HWND for window."); - RawWindowHandle::Windows(WindowsHandle::empty()) } + RawWindowHandle::Win32(handle) } } @@ -264,8 +250,6 @@ trait WndProc { struct MyWndProc { app: Application, handle: RefCell, - d2d_factory: D2DFactory, - text: PietText, state: RefCell>, present_strategy: PresentStrategy, } @@ -273,8 +257,6 @@ struct MyWndProc { /// The mutable state of the window. struct WndState { handler: Box, - render_target: Option, - dxgi_state: Option, min_size: Option, keyboard_state: KeyboardState, // Stores a set of all mouse buttons that are currently holding mouse @@ -427,41 +409,9 @@ fn set_style(hwnd: HWND, resizable: bool, titlebar: bool) { } impl WndState { - fn rebuild_render_target(&mut self, d2d: &D2DFactory, scale: Scale) -> Result<(), Error> { - unsafe { - let swap_chain = self.dxgi_state.as_ref().unwrap().swap_chain; - match paint::create_render_target_dxgi(d2d, swap_chain, scale, self.transparent) { - Ok(rt) => { - self.render_target = - Some(rt.as_device_context().expect("TODO remove this expect")); - Ok(()) - } - Err(e) => Err(e), - } - } - } - // Renders but does not present. - fn render(&mut self, d2d: &D2DFactory, text: &PietText, invalid: &Region) { - let rt = self.render_target.as_mut().unwrap(); - - rt.begin_draw(); - { - let mut piet_ctx = Piet::new(d2d, text.clone(), rt); - - // The documentation on DXGI_PRESENT_PARAMETERS says we "must not update any - // pixel outside of the dirty rectangles." - piet_ctx.clip(invalid.to_bez_path()); - self.handler.paint(&mut piet_ctx, invalid); - if let Err(e) = piet_ctx.finish() { - error!("piet error on render: {:?}", e); - } - } - // Maybe should deal with lost device here... - let res = rt.end_draw(); - if let Err(e) = res { - error!("EndDraw error: {:?}", e); - } + fn render(&mut self, invalid: &Region) { + self.handler.paint(invalid); } fn enter_mouse_capture(&mut self, hwnd: HWND, button: MouseButton) { @@ -739,21 +689,8 @@ impl WndProc for MyWndProc { state.hwnd.set(hwnd); } if let Some(state) = self.state.borrow_mut().as_mut() { - let dxgi_state = unsafe { - create_dxgi_state(self.present_strategy, hwnd, self.is_transparent()) - .unwrap_or_else(|e| { - error!("Creating swapchain failed: {:?}", e); - None - }) - }; - state.dxgi_state = dxgi_state; - let handle = self.handle.borrow().to_owned(); state.handler.connect(&handle.into()); - - if let Err(e) = state.rebuild_render_target(&self.d2d_factory, scale) { - error!("error building render target: {}", e); - } } Some(0) } @@ -823,17 +760,7 @@ impl WndProc for MyWndProc { let invalid = self.take_invalid(); if !invalid.rects().is_empty() { s.handler.rebuild_resources(); - s.render(&self.d2d_factory, &self.text, &invalid); - if let Some(ref mut ds) = s.dxgi_state { - let mut dirty_rects = util::region_to_rectis(&invalid, self.scale()); - let params = DXGI_PRESENT_PARAMETERS { - DirtyRectsCount: dirty_rects.len() as u32, - pDirtyRects: dirty_rects.as_mut_ptr(), - pScrollRect: null_mut(), - pScrollOffset: null_mut(), - }; - (*ds.swap_chain).Present1(1, 0, ¶ms); - } + s.render(&invalid); } }); Some(0) @@ -947,33 +874,7 @@ impl WndProc for MyWndProc { let size_dp = area.size_dp(); self.set_area(area); s.handler.size(size_dp); - let res; - { - s.render_target = None; - res = (*s.dxgi_state.as_mut().unwrap().swap_chain).ResizeBuffers( - 0, - width, - height, - DXGI_FORMAT_UNKNOWN, - 0, - ); - } - if SUCCEEDED(res) { - if let Err(e) = s.rebuild_render_target(&self.d2d_factory, scale) { - error!("error building render target: {}", e); - } - s.render(&self.d2d_factory, &self.text, &size_dp.to_rect().into()); - let present_after = match self.present_strategy { - PresentStrategy::Sequential => 1, - _ => 0, - }; - if let Some(ref mut dxgi_state) = s.dxgi_state { - (*dxgi_state.swap_chain).Present(present_after, 0); - } - ValidateRect(hwnd, null_mut()); - } else { - error!("ResizeBuffers failed: 0x{:x}", res); - } + s.render(&size_dp.to_rect().into()); }) .map(|_| 0) }, @@ -1348,14 +1249,9 @@ impl WindowBuilder { pub fn build(self) -> Result { unsafe { let class_name = super::util::CLASS_NAME.to_wide(); - let dwrite_factory = DwriteFactory::new().unwrap(); - let fonts = self.app.fonts.clone(); - let text = PietText::new_with_shared_fonts(dwrite_factory, Some(fonts)); let wndproc = MyWndProc { app: self.app.clone(), handle: Default::default(), - d2d_factory: D2DFactory::new().unwrap(), - text: text.clone(), state: RefCell::new(None), present_strategy: self.present_strategy, }; @@ -1441,14 +1337,11 @@ impl WindowBuilder { }; let win = Rc::new(window); let handle = WindowHandle { - text, state: Rc::downgrade(&win), }; let state = WndState { handler: self.handler.unwrap(), - render_target: None, - dxgi_state: None, min_size: self.min_size, keyboard_state: KeyboardState::new(), captured_mouse_buttons: MouseButtons::new(), @@ -1589,121 +1482,6 @@ unsafe fn choose_adapter(factory: *mut IDXGIFactory2) -> *mut IDXGIAdapter { best_adapter } -unsafe fn create_dxgi_state( - present_strategy: PresentStrategy, - hwnd: HWND, - transparent: bool, -) -> Result, Error> { - let mut factory: *mut IDXGIFactory2 = null_mut(); - as_result(CreateDXGIFactory1( - &IID_IDXGIFactory2, - &mut factory as *mut *mut IDXGIFactory2 as *mut *mut c_void, - ))?; - debug!("dxgi factory pointer = {:?}", factory); - let adapter = choose_adapter(factory); - debug!("adapter = {:?}", adapter); - - let mut d3d11_device = D3D11Device::new_simple()?; - - let (swap_effect, bufs) = match present_strategy { - PresentStrategy::Sequential => (DXGI_SWAP_EFFECT_SEQUENTIAL, 1), - PresentStrategy::Flip | PresentStrategy::FlipRedirect => { - (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, 2) - } - }; - - let desc = DXGI_SWAP_CHAIN_DESC1 { - Width: 1024, - Height: 768, - Format: DXGI_FORMAT_B8G8R8A8_UNORM, - Stereo: FALSE, - SampleDesc: DXGI_SAMPLE_DESC { - Count: 1, - Quality: 0, - }, - BufferUsage: DXGI_USAGE_RENDER_TARGET_OUTPUT, - BufferCount: bufs, - Scaling: DXGI_SCALING_STRETCH, - SwapEffect: swap_effect, - AlphaMode: if transparent { - DXGI_ALPHA_MODE_PREMULTIPLIED - } else { - DXGI_ALPHA_MODE_IGNORE - }, - Flags: 0, - }; - let mut swap_chain: *mut IDXGISwapChain1 = null_mut(); - let swap_chain_res = if transparent { - (*factory).CreateSwapChainForComposition( - d3d11_device.raw_ptr() as *mut IUnknown, - &desc, - null_mut(), - &mut swap_chain, - ) - } else { - (*factory).CreateSwapChainForHwnd( - d3d11_device.raw_ptr() as *mut IUnknown, - hwnd, - &desc, - null_mut(), - null_mut(), - &mut swap_chain, - ) - }; - debug!( - "swap chain res = 0x{:x}, pointer = {:?}", - swap_chain_res, swap_chain - ); - - let (composition_device, composition_target, composition_visual) = if transparent { - // This behavior is only supported on windows 8 and newer where - // composition is available - - // Following resources are created according to this tutorial: - // https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/june/windows-with-c-high-performance-window-layering-using-the-windows-composition-engine - let DCompositionCreateDevice = OPTIONAL_FUNCTIONS.DCompositionCreateDevice.unwrap(); - - // Create IDCompositionDevice - let mut ptr: *mut c_void = null_mut(); - DCompositionCreateDevice( - d3d11_device.raw_ptr() as *mut IDXGIDevice, - &IDCompositionDevice::uuidof(), - &mut ptr, - ); - let composition_device = ComPtr::::from_raw(ptr as _); - - // Create IDCompositionTarget for the window - let mut ptr: *mut IDCompositionTarget = null_mut(); - composition_device.CreateTargetForHwnd(hwnd as _, 1, &mut ptr); - let composition_target = ComPtr::from_raw(ptr); - - // Create IDCompositionVisual and assign to swap chain - let mut ptr: *mut IDCompositionVisual = null_mut(); - composition_device.CreateVisual(&mut ptr); - let composition_visual = ComPtr::from_raw(ptr); - composition_visual.SetContent(swap_chain as *mut IUnknown); - - // Set the root as composition target and commit - composition_target.SetRoot(composition_visual.as_raw()); - composition_device.Commit(); - - ( - Some(composition_device), - Some(composition_target), - Some(composition_visual), - ) - } else { - (None, None, None) - }; - - Ok(Some(DxgiState { - swap_chain, - composition_device, - composition_target, - composition_visual, - })) -} - #[cfg(target_arch = "x86_64")] type WindowLongPtr = winapi::shared::basetsd::LONG_PTR; #[cfg(target_arch = "x86")] @@ -2060,10 +1838,6 @@ impl WindowHandle { self.defer(DeferredOp::ContextMenu(menu, pos)); } - pub fn text(&self) -> PietText { - self.text.clone() - } - pub fn add_text_field(&self) -> TextFieldToken { TextFieldToken::next() } @@ -2127,8 +1901,8 @@ impl WindowHandle { } defer!(DeleteDC(bmp_dc);); - let width = cursor_desc.image.width(); - let height = cursor_desc.image.height(); + let width = 1; + let height = 1; let mask = CreateCompatibleBitmap(hdc, width as c_int, height as c_int); if mask.is_null() { return None; @@ -2144,16 +1918,16 @@ impl WindowHandle { let old_mask = SelectObject(mask_dc, mask as *mut c_void); let old_bmp = SelectObject(bmp_dc, bmp as *mut c_void); - for (row_idx, row) in cursor_desc.image.pixel_colors().enumerate() { - for (col_idx, p) in row.enumerate() { - let (r, g, b, a) = p.as_rgba8(); - // TODO: what's the story on partial transparency? I couldn't find documentation. - let mask_px = RGB(255 - a, 255 - a, 255 - a); - let bmp_px = RGB(r, g, b); - SetPixel(mask_dc, col_idx as i32, row_idx as i32, mask_px); - SetPixel(bmp_dc, col_idx as i32, row_idx as i32, bmp_px); - } - } + // for (row_idx, row) in cursor_desc.image.pixel_colors().enumerate() { + // for (col_idx, p) in row.enumerate() { + // let (r, g, b, a) = p.as_rgba8(); + // // TODO: what's the story on partial transparency? I couldn't find documentation. + // let mask_px = RGB(255 - a, 255 - a, 255 - a); + // let bmp_px = RGB(r, g, b); + // SetPixel(mask_dc, col_idx as i32, row_idx as i32, mask_px); + // SetPixel(bmp_dc, col_idx as i32, row_idx as i32, bmp_px); + // } + // } SelectObject(mask_dc, old_mask); SelectObject(bmp_dc, old_bmp); @@ -2282,7 +2056,6 @@ impl Default for WindowHandle { fn default() -> Self { WindowHandle { state: Default::default(), - text: PietText::new_with_shared_fonts(DwriteFactory::new().unwrap(), None), } } } diff --git a/druid-shell/src/backend/x11/window.rs b/druid-shell/src/backend/x11/window.rs index db61b5d2c6..726fff45bd 100644 --- a/druid-shell/src/backend/x11/window.rs +++ b/druid-shell/src/backend/x11/window.rs @@ -41,7 +41,6 @@ use x11rb::protocol::xproto::{ use x11rb::wrapper::ConnectionExt as _; use x11rb::xcb_ffi::XCBConnection; -#[cfg(feature = "raw-win-handle")] use raw_window_handle::{unix::XcbHandle, HasRawWindowHandle, RawWindowHandle}; use crate::backend::shared::Timer; @@ -1843,7 +1842,6 @@ impl WindowHandle { } } -#[cfg(feature = "raw-win-handle")] unsafe impl HasRawWindowHandle for WindowHandle { fn raw_window_handle(&self) -> RawWindowHandle { let mut handle = XcbHandle { diff --git a/druid-shell/src/lib.rs b/druid-shell/src/lib.rs index 0e2b01d36b..8d1d355dab 100644 --- a/druid-shell/src/lib.rs +++ b/druid-shell/src/lib.rs @@ -46,10 +46,8 @@ extern crate gtk_rs as gtk; pub use image; pub use kurbo; -pub use piet_common as piet; // Reexport the version of `raw_window_handle` we are using. -#[cfg(feature = "raw-win-handle")] pub use raw_window_handle; #[macro_use] diff --git a/druid-shell/src/mouse.rs b/druid-shell/src/mouse.rs index a080d38369..ddd15f52da 100644 --- a/druid-shell/src/mouse.rs +++ b/druid-shell/src/mouse.rs @@ -16,7 +16,6 @@ use crate::backend; use crate::kurbo::{Point, Vec2}; -use crate::piet::ImageBuf; use crate::Modifiers; /// Information about the mouse event. @@ -270,8 +269,8 @@ pub enum Cursor { /// A platform-independent description of a custom cursor. #[derive(Clone)] pub struct CursorDesc { - #[allow(dead_code)] // Not yet used on all platforms. - pub(crate) image: ImageBuf, + // #[allow(dead_code)] // Not yet used on all platforms. + // pub(crate) image: ImageBuf, #[allow(dead_code)] // Not yet used on all platforms. pub(crate) hot: Point, } @@ -283,11 +282,8 @@ impl CursorDesc { /// `(0, 0)` at the top left. The hot spot is the logical position of the mouse cursor within /// the image. For example, if the image is a picture of a arrow, the hot spot might be the /// coordinates of the arrow's tip. - pub fn new(image: ImageBuf, hot: impl Into) -> CursorDesc { - CursorDesc { - image, - hot: hot.into(), - } + pub fn new(hot: impl Into) -> CursorDesc { + CursorDesc { hot: hot.into() } } } diff --git a/druid-shell/src/text.rs b/druid-shell/src/text.rs index 501351b371..6b9104198a 100644 --- a/druid-shell/src/text.rs +++ b/druid-shell/src/text.rs @@ -103,7 +103,6 @@ use crate::keyboard::{KbKey, KeyEvent}; use crate::kurbo::{Point, Rect}; -use crate::piet::HitTestPoint; use crate::window::{TextFieldToken, WinHandler}; use std::borrow::Cow; use std::ops::Range; @@ -419,7 +418,7 @@ pub trait InputHandler { fn replace_range(&mut self, range: Range, text: &str); /// Given a `Point`, determine the corresponding text position. - fn hit_test_point(&self, point: Point) -> HitTestPoint; + // fn hit_test_point(&self, point: Point) -> HitTestPoint; /// Returns the range, in UTF-8 code units, of the line (soft- or hard-wrapped) /// containing the byte specified by `index`. diff --git a/druid-shell/src/window.rs b/druid-shell/src/window.rs index 5cb2beed94..6ccf021be3 100644 --- a/druid-shell/src/window.rs +++ b/druid-shell/src/window.rs @@ -29,8 +29,7 @@ use crate::mouse::{Cursor, CursorDesc, MouseEvent}; use crate::region::Region; use crate::scale::Scale; use crate::text::{Event, InputHandler}; -use piet_common::PietText; -#[cfg(feature = "raw-win-handle")] + use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; /// A token that uniquely identifies a running timer. @@ -311,11 +310,6 @@ impl WindowHandle { self.0.set_menu(menu.into_inner()) } - /// Get access to a type that can perform text layout. - pub fn text(&self) -> PietText { - self.0.text() - } - /// Register a new text input receiver for this window. /// /// This method should be called any time a new editable text field is @@ -418,7 +412,6 @@ impl WindowHandle { } } -#[cfg(feature = "raw-win-handle")] unsafe impl HasRawWindowHandle for WindowHandle { fn raw_window_handle(&self) -> RawWindowHandle { self.0.raw_window_handle() @@ -557,7 +550,7 @@ pub trait WinHandler { /// Request the handler to paint the window contents. `invalid` is the region in [display /// points](crate::Scale) that needs to be repainted; painting outside the invalid region will /// have no effect. - fn paint(&mut self, piet: &mut piet_common::Piet, invalid: &Region); + fn paint(&mut self, invalid: &Region); /// Called when the resources need to be rebuilt. /// diff --git a/druid/Cargo.toml b/druid/Cargo.toml index 110c237fcc..b794b72128 100644 --- a/druid/Cargo.toml +++ b/druid/Cargo.toml @@ -31,9 +31,6 @@ wayland = ["druid-shell/wayland"] crochet = [] serde = ["im/serde", "druid-shell/serde"] -# Implement HasRawWindowHandle for WindowHandle -raw-win-handle = ["druid-shell/raw-win-handle"] - # passing on all the image features. AVIF is not supported because it does not # support decoding, and that's all we use `Image` for. png = ["druid-shell/image_png"] diff --git a/druid/src/lib.rs b/druid/src/lib.rs index cad1b4695c..7e857c4178 100644 --- a/druid/src/lib.rs +++ b/druid/src/lib.rs @@ -198,7 +198,6 @@ pub use shell::{ WindowHandle, WindowLevel, WindowState, }; -#[cfg(feature = "raw-win-handle")] pub use crate::shell::raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; pub use crate::core::{WidgetPod, WidgetState}; diff --git a/druid/src/text/input_component.rs b/druid/src/text/input_component.rs index cb030911ec..163257f9eb 100644 --- a/druid/src/text/input_component.rs +++ b/druid/src/text/input_component.rs @@ -877,14 +877,14 @@ impl InputHandler for EditSessionHandle { self.inner.borrow_mut().external_text_change = Some(self.text.clone()); } - fn hit_test_point(&self, point: Point) -> crate::piet::HitTestPoint { - self.inner - .borrow() - .layout - .layout() - .map(|layout| layout.hit_test_point(point)) - .unwrap_or_default() - } + // fn hit_test_point(&self, point: Point) -> crate::piet::HitTestPoint { + // self.inner + // .borrow() + // .layout + // .layout() + // .map(|layout| layout.hit_test_point(point)) + // .unwrap_or_default() + // } fn line_range(&self, index: usize, _affinity: druid_shell::text::Affinity) -> Range { let inner = self.inner.borrow();