mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 04:54:45 +00:00
Merge pull request #5211 from dotCooCoo/fix/brand-mark-under-desktop-frame
Title bar: the app bar shows no brand mark under the desktop's own frame
This commit is contained in:
@@ -467,6 +467,7 @@ fn main() -> std::process::ExitCode {
|
||||
rs.device.set_device_lost_callback(move |reason, msg| loss.report(&ctx, format!("{reason:?}: {msg}")));
|
||||
}
|
||||
app.custom_titlebar = custom_titlebar;
|
||||
app.desktop_frame = !custom_titlebar;
|
||||
if let Some(port) = control_port {
|
||||
let rx = control_server::start(port, cc.egui_ctx.clone());
|
||||
app = app.with_control(rx).with_automation_roots(roots.clone());
|
||||
|
||||
@@ -123,6 +123,7 @@ impl VectorcraftApp {
|
||||
canvas_rect: None,
|
||||
hover_doc: None,
|
||||
custom_titlebar: false,
|
||||
desktop_frame: false,
|
||||
last_window_title: String::new(),
|
||||
fullscreen_for_mode: false,
|
||||
graphics_adapter: None,
|
||||
|
||||
@@ -129,13 +129,15 @@ pub fn app_bar(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the window shows the system's title bar instead of the app drawing its own: Windows
|
||||
/// and Linux with Preferences › User Interface › System Title Bar. macOS always has system
|
||||
/// decorations, but keeps the in-app brand mark, so it never counts as system mode here; nor
|
||||
/// does the web build (the browser tab has no document title), nor an embedder that never
|
||||
/// turned the preference on.
|
||||
/// Whether the window shows the system's title bar instead of the app drawing its own
|
||||
/// ([`VectorcraftApp::desktop_frame`]): Windows with Preferences › User Interface › System Title
|
||||
/// Bar, and Linux whenever the desktop draws the frame, with or without the preference. The
|
||||
/// preference is read when the app starts, so changing it later does not change this. macOS
|
||||
/// always has system decorations, but keeps the in-app brand mark, so it never counts as system
|
||||
/// mode here; nor does the web build (the browser tab has no document title), nor an embedder
|
||||
/// without a window of its own.
|
||||
pub fn system_title_bar(app: &VectorcraftApp) -> bool {
|
||||
!app.custom_titlebar && app.session.prefs.system_title_bar && !cfg!(any(target_os = "macos", target_arch = "wasm32"))
|
||||
app.desktop_frame && !app.custom_titlebar && !cfg!(any(target_os = "macos", target_arch = "wasm32"))
|
||||
}
|
||||
|
||||
/// The OS window title: the active document's name suffixed with the app name (a `*` prefix
|
||||
|
||||
@@ -1230,16 +1230,51 @@ fn the_zoom_hint_follows_animated_zoom() {
|
||||
fn title_test_app(custom_titlebar: bool) -> crate::VectorcraftApp {
|
||||
let mut app = crate::VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.custom_titlebar = custom_titlebar;
|
||||
app.desktop_frame = !custom_titlebar;
|
||||
// The preference that makes the shell launch without its own title bar.
|
||||
app.run("prefs.set", json!({"key": "systemTitleBar", "value": !custom_titlebar})).unwrap();
|
||||
app
|
||||
}
|
||||
|
||||
/// How many brand marks one frame of the app bar paints.
|
||||
fn brand_marks(app: &mut crate::VectorcraftApp) -> usize {
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
let mut out = ctx.run_ui(egui::RawInput::default(), |ui| super::app_bar(app, ui));
|
||||
out.textures_delta.clear();
|
||||
out.shapes.iter().filter(|c| matches!(&c.shape, egui::Shape::Mesh(m) if m.texture_id == crate::brand::texture_id(&ctx))).count()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn without_the_preference_the_mark_stays() {
|
||||
// The default (e.g. the web build): no custom bar, no preference.
|
||||
let app = crate::VectorcraftApp::new(Session::new(), Default::default());
|
||||
assert!(!super::system_title_bar(&app));
|
||||
// An embedder without a window of its own keeps the mark with the preference on too.
|
||||
let mut app = crate::VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("prefs.set", json!({"key": "systemTitleBar", "value": true})).unwrap();
|
||||
assert!(!super::system_title_bar(&app));
|
||||
assert_eq!(brand_marks(&mut app), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_desktop_frame_hides_the_mark_whatever_the_preference_says() {
|
||||
// Linux on a desktop that draws the frame (KDE, X11): the window has the desktop's title bar
|
||||
// with System Title Bar off.
|
||||
let mut app = crate::VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.desktop_frame = true;
|
||||
app.run("prefs.set", json!({"key": "systemTitleBar", "value": false})).unwrap();
|
||||
let hidden = !cfg!(target_os = "macos");
|
||||
assert_eq!(super::system_title_bar(&app), hidden);
|
||||
assert_eq!(brand_marks(&mut app), if hidden { 0 } else { 1 });
|
||||
// The preference applies at the next start: changing it now leaves the window's frame, and the mark, as they are.
|
||||
let mut app = title_test_app(false);
|
||||
app.run("prefs.set", json!({"key": "systemTitleBar", "value": false})).unwrap();
|
||||
assert_eq!(super::system_title_bar(&app), hidden);
|
||||
let mut app = title_test_app(true);
|
||||
app.run("prefs.set", json!({"key": "systemTitleBar", "value": true})).unwrap();
|
||||
assert!(!super::system_title_bar(&app));
|
||||
assert_eq!(brand_marks(&mut app), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -198,6 +198,10 @@ pub struct VectorcraftApp {
|
||||
/// Windows and Linux: the window has no OS decorations, so the app bar is the title bar (drag,
|
||||
/// double-click to maximize, caption buttons) and invisible edge zones resize the window.
|
||||
pub custom_titlebar: bool,
|
||||
/// The window has the desktop's own title bar: the OS or the window manager draws its frame,
|
||||
/// icon and title. Set by the desktop app when it opens the window; `false` for embedders
|
||||
/// without a window of their own.
|
||||
pub desktop_frame: bool,
|
||||
/// Last window title sent to the OS (`ViewportCommand::Title`, see `chrome::sync_window_title`):
|
||||
/// sent again only when it changes, so idle frames don't spam the backend.
|
||||
pub(crate) last_window_title: String,
|
||||
|
||||
@@ -328,7 +328,8 @@ not commands, so drive them with `ui.click` if needed. Close runs `app.quit` (th
|
||||
modified documents), and empty bar space and the 5 pt window edges move and resize the window. Preferences › User
|
||||
Interface › System Title Bar (`systemTitleBar`, read when the app starts) gives the window its OS decorations back
|
||||
instead: the OS title then shows the active document (`*name — VectorCraft` with unsaved changes) and the app bar
|
||||
drops its brand mark. On macOS the window buttons are centred on the app bar; the web build is unchanged.
|
||||
drops its brand mark. On Linux the app bar also drops its brand mark whenever the desktop draws the window's frame, with
|
||||
System Title Bar on or off. On macOS the window buttons are centred on the app bar; the web build is unchanged.
|
||||
|
||||
Fill/Stroke chips and panel shortcuts: the Control bar's and Properties' Fill and Stroke chips bring their proxy
|
||||
forward (`paint.toggleActive {fill}`) and open a popover with the Swatches panel (Shift-click: the Color panel's mixer);
|
||||
|
||||
Reference in New Issue
Block a user