linux impl?

This commit is contained in:
Lucas Nogueira
2026-01-26 14:25:57 -03:00
parent faf7d48f2f
commit 26e5d8f8c3
4 changed files with 165 additions and 8 deletions

1
Cargo.lock generated
View File

@@ -9093,6 +9093,7 @@ dependencies = [
"tauri-utils",
"url",
"windows 0.61.1",
"x11-dl",
]
[[package]]

View File

@@ -36,6 +36,7 @@ objc2-foundation = { version = "0.3", features = ["NSNotification"] }
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
gtk = { version = "0.18", features = ["v3_24"] }
x11-dl = "2.21"
[features]
default = ["sandbox"]

View File

@@ -100,4 +100,6 @@ trait CefBrowserExt {
fn nsview(&self) -> Option<objc2::rc::Retained<objc2_app_kit::NSView>>;
#[cfg(windows)]
fn hwnd(&self) -> Option<::windows::Win32::Foundation::HWND>;
#[cfg(target_os = "linux")]
fn xid(&self) -> Option<u64>;
}

View File

@@ -1,33 +1,186 @@
use cef::*;
use std::sync::LazyLock;
use x11_dl::xlib;
use crate::cef_webview::CefBrowserExt;
static X11: LazyLock<Option<xlib::Xlib>> = LazyLock::new(|| xlib::Xlib::open().ok());
impl CefBrowserExt for cef::Browser {
fn xid(&self) -> Option<u64> {
let host = self.host()?;
let xid = host.window_handle() as u64;
Some(xid)
}
fn bounds(&self) -> cef::Rect {
todo!()
let Some(xid) = self.xid() else {
return cef::Rect::default();
};
let Some(xlib) = X11.as_ref() else {
return cef::Rect::default();
};
unsafe {
let display = (xlib.XOpenDisplay)(std::ptr::null());
if display.is_null() {
return cef::Rect::default();
}
let mut root: xlib::Window = 0;
let mut x: i32 = 0;
let mut y: i32 = 0;
let mut width: u32 = 0;
let mut height: u32 = 0;
let mut border_width: u32 = 0;
let mut depth: u32 = 0;
let status = (xlib.XGetGeometry)(
display,
xid as xlib::Window,
&mut root,
&mut x,
&mut y,
&mut width,
&mut height,
&mut border_width,
&mut depth,
);
(xlib.XCloseDisplay)(display);
if status == 0 {
return cef::Rect::default();
}
// XGetGeometry returns position relative to parent, which is what we need
cef::Rect {
x,
y,
width: width as i32,
height: height as i32,
}
}
}
fn set_bounds(&self, rect: Option<&cef::Rect>) {
todo!()
let Some(rect) = rect else {
return;
};
let Some(xid) = self.xid() else {
return;
};
let Some(xlib) = X11.as_ref() else {
return;
};
unsafe {
let display = (xlib.XOpenDisplay)(std::ptr::null());
if display.is_null() {
return;
}
(xlib.XMoveResizeWindow)(
display,
xid as xlib::Window,
rect.x,
rect.y,
rect.width as u32,
rect.height as u32,
);
(xlib.XFlush)(display);
(xlib.XCloseDisplay)(display);
}
}
fn scale_factor(&self) -> f64 {
todo!()
// Get scale factor from primary display
// CEF on Linux doesn't provide direct access to the window's display,
// so we use the primary display as a reasonable default
cef::display_get_primary()
.map(|d| d.device_scale_factor() as f64)
.unwrap_or(1.0)
}
fn set_background_color(&self, color: cef::Color) {
// TODO:
fn set_background_color(&self, _color: cef::Color) {
// TODO: Implement background color setting for Linux/X11
}
fn set_visible(&self, visible: i32) {
todo!()
let Some(xid) = self.xid() else {
return;
};
let Some(xlib) = X11.as_ref() else {
return;
};
unsafe {
let display = (xlib.XOpenDisplay)(std::ptr::null());
if display.is_null() {
return;
}
if visible != 0 {
(xlib.XMapWindow)(display, xid as xlib::Window);
} else {
(xlib.XUnmapWindow)(display, xid as xlib::Window);
}
(xlib.XFlush)(display);
(xlib.XCloseDisplay)(display);
}
}
fn close(&self) {
todo!()
let Some(xid) = self.xid() else {
return;
};
let Some(xlib) = X11.as_ref() else {
return;
};
unsafe {
let display = (xlib.XOpenDisplay)(std::ptr::null());
if display.is_null() {
return;
}
(xlib.XDestroyWindow)(display, xid as xlib::Window);
(xlib.XFlush)(display);
(xlib.XCloseDisplay)(display);
}
}
fn set_parent(&self, parent: &cef::Window) {
todo!()
let Some(xid) = self.xid() else {
return;
};
let parent_xid = parent.window_handle() as u64;
let Some(xlib) = X11.as_ref() else {
return;
};
unsafe {
let display = (xlib.XOpenDisplay)(std::ptr::null());
if display.is_null() {
return;
}
(xlib.XReparentWindow)(
display,
xid as xlib::Window,
parent_xid as xlib::Window,
0,
0,
);
(xlib.XFlush)(display);
(xlib.XCloseDisplay)(display);
}
}
}