The C-ABI? Who would want access to that? Oh, the Linux Viewport perhaps.

This commit is contained in:
jess 2026-04-29 12:04:12 -07:00
parent 9354515aea
commit 88ba5ecf9c
3 changed files with 55 additions and 58 deletions

View File

@ -10,7 +10,7 @@ use winit::keyboard::{Key, ModifiersState, NamedKey};
use winit::window::{Window, WindowAttributes, WindowId};
use acord_viewport::{
viewport_create, viewport_destroy, viewport_render, viewport_resize,
viewport_destroy, viewport_render, viewport_resize,
viewport_set_text, viewport_get_text, viewport_set_theme, viewport_set_lang,
viewport_set_line_indicator, viewport_set_gutter_rainbow,
viewport_set_auto_pair_flags,
@ -18,6 +18,7 @@ use acord_viewport::{
ViewportHandle,
};
use acord_viewport::browser::{self, BrowserHandle};
use acord_viewport::handle as viewport_handle;
use crate::config::Config;
use crate::shortcuts::{match_shortcut, MenuAction};
@ -368,25 +369,19 @@ impl ApplicationHandler for App {
let w = size.width as f32 / self.scale;
let h = size.height as f32 / self.scale;
// Pass the raw display+window handle to the viewport. wgpu picks the
// X11 or Wayland backend automatically based on which RawDisplayHandle
// variant winit hands us, so a single binary works on both.
use raw_window_handle::HasWindowHandle;
let wh = window.window_handle().expect("window handle");
let raw = wh.as_raw();
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
let display = window.display_handle().expect("display handle").as_raw();
let win_handle = window.window_handle().expect("window handle").as_raw();
let surface_handle = match raw {
#[cfg(target_os = "linux")]
raw_window_handle::RawWindowHandle::Xlib(h) => h.window as *mut std::ffi::c_void,
#[cfg(target_os = "linux")]
raw_window_handle::RawWindowHandle::Xcb(h) => h.window.get() as *mut std::ffi::c_void,
#[cfg(target_os = "linux")]
raw_window_handle::RawWindowHandle::Wayland(h) => h.surface.as_ptr(),
_ => std::ptr::null_mut(),
};
self.handle = viewport_create(surface_handle, w, h, self.scale);
self.sync_settings();
match viewport_handle::create_native(display, win_handle, w, h, self.scale) {
Some(h) => {
self.handle = Box::into_raw(Box::new(h));
self.sync_settings();
}
None => {
eprintln!("acord: failed to create viewport surface");
}
}
self.window = Some(window);
}

View File

@ -1,31 +1,19 @@
use std::ffi::c_void;
use std::ptr::NonNull;
use iced_graphics::Viewport;
use iced_runtime::user_interface::UserInterface;
use iced_graphics::{Shell, Viewport};
use iced_runtime::user_interface::{self, UserInterface};
use iced_wgpu::core::renderer::Style;
use iced_wgpu::core::time::Instant;
use iced_wgpu::core::{clipboard, keyboard, mouse, window, Color, Event, Size, Theme};
#[cfg(any(target_os = "macos", target_os = "windows"))]
use std::ptr::NonNull;
#[cfg(any(target_os = "macos", target_os = "windows"))]
use iced_graphics::Shell;
#[cfg(any(target_os = "macos", target_os = "windows"))]
use iced_runtime::user_interface;
#[cfg(any(target_os = "macos", target_os = "windows"))]
use iced_wgpu::core::{Font, Pixels, Point};
#[cfg(any(target_os = "macos", target_os = "windows"))]
use iced_wgpu::core::{clipboard, keyboard, mouse, window, Color, Event, Font, Pixels, Point, Size, Theme};
use iced_wgpu::Engine;
#[cfg(any(target_os = "macos", target_os = "windows"))]
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
#[cfg(target_os = "macos")]
use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle};
#[cfg(target_os = "windows")]
use raw_window_handle::{Win32WindowHandle, WindowsDisplayHandle};
#[cfg(any(target_os = "macos", target_os = "windows"))]
use crate::editor::EditorState;
use crate::editor::{Message, RenderMode};
use crate::editor::{EditorState, Message, RenderMode};
use crate::palette;
use crate::table_block::TableMessage;
use crate::ViewportHandle;
@ -60,17 +48,10 @@ impl clipboard::Clipboard for AcordClipboard {
}
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
pub fn create(
_native_handle: *mut c_void,
_width: f32,
_height: f32,
_scale: f32,
) -> Option<ViewportHandle> {
None
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
/// Mac/Windows entry point used by the C FFI. Synthesizes the platform's
/// display handle from the window pointer the Swift bridge provides.
/// Returns None on platforms that need both display and window — those
/// shells should call `create_native` directly.
pub fn create(
native_handle: *mut c_void,
width: f32,
@ -79,16 +60,6 @@ pub fn create(
) -> Option<ViewportHandle> {
let ptr = NonNull::new(native_handle)?;
#[cfg(target_os = "macos")]
let backends = wgpu::Backends::METAL;
#[cfg(target_os = "windows")]
let backends = wgpu::Backends::DX12;
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
backends,
..Default::default()
});
#[cfg(target_os = "macos")]
let (raw_window, raw_display) = (
RawWindowHandle::AppKit(AppKitWindowHandle::new(ptr)),
@ -102,6 +73,37 @@ pub fn create(
RawDisplayHandle::Windows(WindowsDisplayHandle::new()),
)
};
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
{
let _ = (ptr, width, height, scale);
return None;
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
create_native(raw_display, raw_window, width, height, scale)
}
/// Rust-native entry point. Takes typed handles directly so shells that own
/// a winit Window (Linux, future Windows refactor) can build a surface
/// without going through the C FFI's single-pointer compromise.
pub fn create_native(
raw_display: RawDisplayHandle,
raw_window: RawWindowHandle,
width: f32,
height: f32,
scale: f32,
) -> Option<ViewportHandle> {
#[cfg(target_os = "macos")]
let backends = wgpu::Backends::METAL;
#[cfg(target_os = "windows")]
let backends = wgpu::Backends::DX12;
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
let backends = wgpu::Backends::VULKAN | wgpu::Backends::GL;
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
backends,
..Default::default()
});
let target = wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: raw_display,

View File

@ -6,7 +6,7 @@ mod bridge;
pub mod browser;
mod editor;
pub mod export;
mod handle;
pub mod handle;
pub mod heading_block;
pub mod hr_block;
pub mod module;