mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(linux): enable floating window frame by default on GNOME
This commit is contained in:
@@ -35,15 +35,15 @@ description: DBX 常见问题:连接数据保存在哪里、如何备份、如
|
||||
|
||||
## Linux 窗口闪烁或内容消失
|
||||
|
||||
Linux 主窗口默认使用不透明背景,避免部分 KDE、显卡驱动与 WebKitGTK 的透明窗口合成兼容问题。不会因此关闭 GPU 加速或改变 Wayland/X11 后端。
|
||||
在 GNOME 且系统已开启窗口合成时,Linux 主窗口会绘制带圆角、阴影的浮动边框;在其他桌面(KDE、XFCE、Cinnamon 等)默认使用不透明背景,避免部分显卡驱动与 WebKitGTK 的透明窗口合成兼容问题。两种模式都不会关闭 GPU 加速或改变 Wayland/X11 后端。
|
||||
|
||||
如果确认当前环境支持透明窗口,可以显式启用带圆角、阴影的浮动边框:
|
||||
可以通过环境变量覆盖默认行为。在其他桌面强制启用浮动边框:
|
||||
|
||||
```bash
|
||||
DBX_LINUX_FLOATING_FRAME=1 dbx
|
||||
```
|
||||
|
||||
只有环境变量值为 `1` 且系统已开启窗口合成时才启用。若启用后出现闪烁、内容消失或必须缩放窗口才能重绘,请完全退出 DBX(包括托盘),移除该环境变量或使用 `DBX_LINUX_FLOATING_FRAME=0 dbx` 重新启动。AppImage 用户请将 `dbx` 替换为实际的 AppImage 文件路径。
|
||||
若在 GNOME 上出现闪烁、内容消失或必须缩放窗口才能重绘,请完全退出 DBX(包括托盘),并使用 `DBX_LINUX_FLOATING_FRAME=0 dbx` 重新启动以强制使用不透明窗口。没有窗口合成时始终不启用浮动边框。AppImage 用户请将 `dbx` 替换为实际的 AppImage 文件路径。
|
||||
|
||||
如果默认的不透明窗口仍有问题,请在反馈中提供 DBX 版本、安装方式、KDE/Plasma 版本、Wayland/X11 会话类型、显卡及驱动信息,以及系统 WebKitGTK 版本。
|
||||
|
||||
|
||||
@@ -35,15 +35,15 @@ description: Frequently asked questions about DBX, including where connection da
|
||||
|
||||
## Linux Window Flickering or Missing Content
|
||||
|
||||
The Linux main window uses an opaque background by default to avoid transparent-window compositing compatibility problems with some KDE, graphics driver and WebKitGTK combinations. This does not disable GPU acceleration or change the Wayland/X11 backend.
|
||||
The Linux main window draws a rounded, shadowed floating frame on GNOME when a compositing manager is running. On other desktops (KDE, XFCE, Cinnamon, ...) it uses an opaque background by default to avoid transparent-window compositing problems with some graphics driver and WebKitGTK combinations. Neither mode disables GPU acceleration or changes the Wayland/X11 backend.
|
||||
|
||||
If your environment supports transparent windows, you can explicitly enable the floating frame with rounded corners and a shadow:
|
||||
The default can be overridden with an environment variable. To force the floating frame on another desktop:
|
||||
|
||||
```bash
|
||||
DBX_LINUX_FLOATING_FRAME=1 dbx
|
||||
```
|
||||
|
||||
The frame is enabled only when the variable is exactly `1` and a compositing manager is available. If enabling it causes flickering, missing content or redraws only after resizing, quit DBX completely, including its tray process, and remove the variable or restart with `DBX_LINUX_FLOATING_FRAME=0 dbx`. For AppImage installations, replace `dbx` with the actual AppImage path.
|
||||
To force the opaque window on GNOME, for example if you see flickering, missing content or redraws only after resizing, quit DBX completely, including its tray process, and restart with `DBX_LINUX_FLOATING_FRAME=0 dbx`. The frame is never used without a compositing manager. For AppImage installations, replace `dbx` with the actual AppImage path.
|
||||
|
||||
If the default opaque window still has problems, include the DBX version, installation format, KDE/Plasma version, Wayland/X11 session type, graphics hardware and driver details, and system WebKitGTK version in your report.
|
||||
|
||||
|
||||
+46
-14
@@ -176,21 +176,45 @@ pub(crate) fn linux_compositing_available() -> bool {
|
||||
gtk::gdk::Screen::default().is_some_and(|screen| screen.is_composited())
|
||||
}
|
||||
|
||||
/// Desktops where the transparent floating frame is known to render correctly. Others (notably
|
||||
/// KDE, which shows flickering or missing content with some driver/WebKitGTK combinations) keep
|
||||
/// the opaque window unless the user forces the frame on.
|
||||
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
|
||||
fn should_enable_linux_floating_frame(compositing: bool, opt_in: Option<&std::ffi::OsStr>) -> bool {
|
||||
compositing && opt_in == Some(std::ffi::OsStr::new("1"))
|
||||
fn linux_desktop_supports_floating_frame(current_desktop: Option<&std::ffi::OsStr>) -> bool {
|
||||
current_desktop
|
||||
.map(|value| value.to_string_lossy().split(':').any(|name| name.eq_ignore_ascii_case("GNOME")))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// `DBX_LINUX_FLOATING_FRAME=1|0` is an optional override; without it the desktop decides.
|
||||
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
|
||||
fn should_enable_linux_floating_frame(
|
||||
compositing: bool,
|
||||
override_value: Option<&std::ffi::OsStr>,
|
||||
current_desktop: Option<&std::ffi::OsStr>,
|
||||
) -> bool {
|
||||
if !compositing {
|
||||
return false;
|
||||
}
|
||||
match override_value.and_then(|value| value.to_str()) {
|
||||
Some("1") => true,
|
||||
Some("0") => false,
|
||||
_ => linux_desktop_supports_floating_frame(current_desktop),
|
||||
}
|
||||
}
|
||||
|
||||
/// The Linux config declares the main window with `create: false` so its transparency can
|
||||
/// be explicitly opted into at runtime when a compositor is available.
|
||||
/// depend at runtime on the desktop and on whether a compositor is available.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn create_linux_main_window(app: &tauri::App) -> tauri::Result<()> {
|
||||
let Some(config) = app.config().app.windows.iter().find(|window| window.label == "main").cloned() else {
|
||||
return Ok(());
|
||||
};
|
||||
let compositing = linux_compositing_available();
|
||||
let opt_in = std::env::var_os("DBX_LINUX_FLOATING_FRAME");
|
||||
let floating_frame = should_enable_linux_floating_frame(compositing, opt_in.as_deref());
|
||||
let override_value = std::env::var_os("DBX_LINUX_FLOATING_FRAME");
|
||||
let current_desktop = std::env::var_os("XDG_CURRENT_DESKTOP");
|
||||
let floating_frame =
|
||||
should_enable_linux_floating_frame(compositing, override_value.as_deref(), current_desktop.as_deref());
|
||||
log::info!("[WINDOW] Linux main window compositing={compositing}; floating_frame={floating_frame}");
|
||||
let mut builder = tauri::WebviewWindowBuilder::from_config(app.handle(), &config)?.transparent(floating_frame);
|
||||
if floating_frame {
|
||||
@@ -1205,22 +1229,30 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn linux_floating_frame_is_disabled_by_default() {
|
||||
assert!(!should_enable_linux_floating_frame(true, None));
|
||||
assert!(!should_enable_linux_floating_frame(false, None));
|
||||
fn linux_floating_frame_is_enabled_by_default_on_gnome_only() {
|
||||
for desktop in ["GNOME", "ubuntu:GNOME", "gnome", "GNOME-Classic:GNOME"] {
|
||||
assert!(should_enable_linux_floating_frame(true, None, Some(OsStr::new(desktop))), "{desktop}");
|
||||
}
|
||||
for desktop in ["KDE", "XFCE", "X-Cinnamon", "sway", "", "GNOMEISH"] {
|
||||
assert!(!should_enable_linux_floating_frame(true, None, Some(OsStr::new(desktop))), "{desktop}");
|
||||
}
|
||||
assert!(!should_enable_linux_floating_frame(true, None, None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn linux_floating_frame_requires_explicit_opt_in() {
|
||||
assert!(should_enable_linux_floating_frame(true, Some(OsStr::new("1"))));
|
||||
for value in ["", "0", "false", "true", "auto", "yes", "01"] {
|
||||
assert!(!should_enable_linux_floating_frame(true, Some(OsStr::new(value))));
|
||||
fn linux_floating_frame_override_wins_over_desktop() {
|
||||
assert!(should_enable_linux_floating_frame(true, Some(OsStr::new("1")), Some(OsStr::new("KDE"))));
|
||||
assert!(!should_enable_linux_floating_frame(true, Some(OsStr::new("0")), Some(OsStr::new("GNOME"))));
|
||||
for value in ["", "true", "auto", "01"] {
|
||||
assert!(should_enable_linux_floating_frame(true, Some(OsStr::new(value)), Some(OsStr::new("GNOME"))));
|
||||
assert!(!should_enable_linux_floating_frame(true, Some(OsStr::new(value)), Some(OsStr::new("KDE"))));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn linux_floating_frame_requires_compositing_even_when_opted_in() {
|
||||
assert!(!should_enable_linux_floating_frame(false, Some(OsStr::new("1"))));
|
||||
fn linux_floating_frame_requires_compositing() {
|
||||
assert!(!should_enable_linux_floating_frame(false, Some(OsStr::new("1")), Some(OsStr::new("GNOME"))));
|
||||
assert!(!should_enable_linux_floating_frame(false, None, Some(OsStr::new("GNOME"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user