From 032b37837b08b469374bdc4a4e672c92b6bdd567 Mon Sep 17 00:00:00 2001 From: ralfbrown Date: Sat, 18 Jan 2025 14:09:25 -0500 Subject: [PATCH 1/4] rework splash screen to avoid keep-above --- src/common/darktable.c | 23 +++++++++-------------- src/gui/gtk.c | 13 +++---------- src/gui/splash.c | 3 +-- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/common/darktable.c b/src/common/darktable.c index 2942901e4889..e419782391b6 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -1618,6 +1618,8 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load darktable_splash_screen_create(NULL, TRUE); // force the splash screen for the crawl even if user-disabled // scan for cases where the database and xmp files have different timestamps changed_xmp_files = dt_control_crawler_run(); + if(!dt_conf_get_bool("show_splash_screen")) + darktable_splash_screen_destroy(); } } @@ -1818,21 +1820,13 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load // init the gui part of views dt_view_manager_gui_init(darktable.view_manager); - - // now that other initialization is complete, we can show the main window - // we need to do this before Lua is started or we'll either get a hang, or - // the module groups don't get set up correctly - - // start by restoring the main window position as stored in the config file - dt_gui_gtk_load_config(); - gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui)); - // give Gtk a chance to actually process the resizing - dt_gui_process_events(); } /* init lua last, since it's user made stuff it must be in the real environment */ #ifdef USE_LUA darktable_splash_screen_set_progress(_("initializing Lua")); + // after the following Lua startup call, we can no longer use dt_gui_process_events() or we hang; + // this also means no more calls to darktable_splash_screen_set_progress() dt_lua_init(darktable.lua_state.state, lua_command); #else darktable_splash_screen_set_progress(_("")); @@ -1911,8 +1905,6 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load if(changed_xmp_files) dt_control_crawler_show_image_list(changed_xmp_files); - darktable_splash_screen_destroy(); - if(!dt_gimpmode()) dt_start_backtumbs_crawler(); } @@ -1930,10 +1922,13 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load dt_capabilities_add("nonapple"); #endif - // if we hid the main window by iconifying it, make sure to restore its geometry if(init_gui) { - gtk_window_deiconify(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui))); + darktable_splash_screen_destroy(); + // unhide the main window and restore its geometry to that saved in the config file + gtk_widget_set_visible(dt_ui_main_window(darktable.gui->ui), TRUE); + dt_gui_gtk_load_config(); +// gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui)); } dt_print(DT_DEBUG_CONTROL, diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 10b701f11ac4..fb347ea1a2b4 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -775,8 +775,8 @@ int dt_gui_gtk_load_config() const gint x = MAX(0, dt_conf_get_int("ui_last/window_x")); const gint y = MAX(0, dt_conf_get_int("ui_last/window_y")); - gtk_window_move(GTK_WINDOW(widget), x, y); gtk_window_resize(GTK_WINDOW(widget), width, height); + gtk_window_move(GTK_WINDOW(widget), x, y); const gboolean fullscreen = dt_conf_get_bool("ui_last/fullscreen"); if(fullscreen) @@ -1789,20 +1789,13 @@ static void _init_widgets(dt_gui_gtk_t *gui) // Showing everything, to ensure proper instantiation and initialization // then we hide the scroll bars and popup messages again - // before doing this, request that the window be minimized (some WMs - // don't support this, so we can hide it below, but that had issues) -// gtk_window_iconify(GTK_WINDOW(dt_ui_main_window(gui->ui))); -// unfortunately, on some systems the above results in a window which can only be manually deiconified.... gtk_widget_show_all(dt_ui_main_window(gui->ui)); gtk_widget_set_visible(dt_ui_log_msg(gui->ui), FALSE); gtk_widget_set_visible(dt_ui_toast_msg(gui->ui), FALSE); gtk_widget_set_visible(gui->scrollbars.hscrollbar, FALSE); gtk_widget_set_visible(gui->scrollbars.vscrollbar, FALSE); - - // if the WM doesn't support minimization, we want to hide the - // window so that we don't actually see it until the rest of the - // initialization is complete -// gtk_widget_hide(dt_ui_main_window(gui->ui)); //FIXME: on some systems, the main window never un-hides later... + // hide the main window, so that it doesn't cover up the splash screen + gtk_widget_set_visible(dt_ui_main_window(gui->ui), FALSE); // finally, process all accumulated GUI events so that everything is properly // set up before proceeding diff --git a/src/gui/splash.c b/src/gui/splash.c index 7632d57b88d8..38c167844223 100644 --- a/src/gui/splash.c +++ b/src/gui/splash.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2024 darktable developers. + Copyright (C) 2024-2025 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -257,7 +257,6 @@ void darktable_splash_screen_create(GtkWindow *parent_window, gtk_window_set_decorated(GTK_WINDOW(splash_screen), FALSE); gtk_widget_show_all(splash_screen); gtk_widget_hide(GTK_WIDGET(remaining_box)); - gtk_window_set_keep_above(GTK_WINDOW(splash_screen), TRUE); _process_all_gui_events(); } From 9fe6e2a2ae5b90a1e7f397467088c68cc454ed8e Mon Sep 17 00:00:00 2001 From: ralfbrown Date: Mon, 20 Jan 2025 16:16:28 -0500 Subject: [PATCH 2/4] raise splash screen after realizing main window Since setting the main window invisible results in it never showing on some systems, try raising the splash screen (once) to keep the main window from obscuring the splash instead of hiding the main window. --- src/common/darktable.c | 7 ++++--- src/gui/gtk.c | 15 ++++----------- src/gui/splash.c | 9 +++++++++ src/gui/splash.h | 1 + 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/common/darktable.c b/src/common/darktable.c index e419782391b6..037ef9adf8ae 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -1619,7 +1619,10 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load // scan for cases where the database and xmp files have different timestamps changed_xmp_files = dt_control_crawler_run(); if(!dt_conf_get_bool("show_splash_screen")) + { darktable_splash_screen_destroy(); + dt_gui_process_events(); // ensure that the splash screen is removed right away + } } } @@ -1924,11 +1927,9 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load if(init_gui) { - darktable_splash_screen_destroy(); // unhide the main window and restore its geometry to that saved in the config file - gtk_widget_set_visible(dt_ui_main_window(darktable.gui->ui), TRUE); dt_gui_gtk_load_config(); -// gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui)); + darktable_splash_screen_destroy(); } dt_print(DT_DEBUG_CONTROL, diff --git a/src/gui/gtk.c b/src/gui/gtk.c index fb347ea1a2b4..6ff39a9036a5 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -1449,7 +1449,6 @@ int dt_gui_gtk_init(dt_gui_gtk_t *gui) widgets.right_scrolled_window); gtk_container_set_focus_vadjustment (box, gtk_scrolled_window_get_vadjustment (swin)); */ - dt_colorspaces_set_display_profile(DT_COLORSPACE_DISPLAY); // update the profile when the window is moved. resize is already handled in configure() widget = dt_ui_main_window(darktable.gui->ui); g_signal_connect(G_OBJECT(widget), "configure-event", @@ -1794,16 +1793,10 @@ static void _init_widgets(dt_gui_gtk_t *gui) gtk_widget_set_visible(dt_ui_toast_msg(gui->ui), FALSE); gtk_widget_set_visible(gui->scrollbars.hscrollbar, FALSE); gtk_widget_set_visible(gui->scrollbars.vscrollbar, FALSE); - // hide the main window, so that it doesn't cover up the splash screen - gtk_widget_set_visible(dt_ui_main_window(gui->ui), FALSE); - - // finally, process all accumulated GUI events so that everything is properly - // set up before proceeding - for(int i = 0; i < 5; i++) - { - g_usleep(500); - dt_gui_process_events(); - } + // raise the splash screen, so that the main window doesn't cover it + // this call also processes all pending GUI events, ensuring that + // everyting is properly set up before we return + darktable_splash_screen_raise(); } static const dt_action_def_t _action_def_focus_tabs; diff --git a/src/gui/splash.c b/src/gui/splash.c index 38c167844223..25c6ccc7faa0 100644 --- a/src/gui/splash.c +++ b/src/gui/splash.c @@ -306,6 +306,15 @@ void darktable_splash_screen_set_progress_percent(const char *msg, } } +void darktable_splash_screen_raise() +{ + if(splash_screen) + { + gdk_window_raise(gtk_widget_get_window(splash_screen)); + _process_all_gui_events(); + } +} + void darktable_splash_screen_destroy() { if(splash_screen) diff --git a/src/gui/splash.h b/src/gui/splash.h index 985e0aeba500..5faaaaeda1f0 100644 --- a/src/gui/splash.h +++ b/src/gui/splash.h @@ -19,6 +19,7 @@ void darktable_splash_screen_create(GtkWindow *parent, gboolean force); void darktable_splash_screen_set_progress(const char *msg); void darktable_splash_screen_set_progress_percent(const char *msg, double fraction, double elapsed); +void darktable_splash_screen_raise(); void darktable_splash_screen_destroy(); void darktable_splash_screen_get_geometry(gint *x, gint *y, gint *width, gint *height); From acfa14e804c72730c8f5bafd5688fd0be1cd9bdd Mon Sep 17 00:00:00 2001 From: ralfbrown Date: Tue, 21 Jan 2025 10:29:52 -0500 Subject: [PATCH 3/4] don't restore stored window config until after realizing main window --- src/gui/gtk.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 6ff39a9036a5..afb72cabb105 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -1765,20 +1765,15 @@ static void _init_widgets(dt_gui_gtk_t *gui) // configure main window position, colors, fonts, etc. gint splash_x, splash_y, splash_w, splash_h; darktable_splash_screen_get_geometry(&splash_x, &splash_y, &splash_w, &splash_h); - if(splash_w == -1) - { - // use the previously-saved geometry; we'll be setting the window to this size later anyway - dt_gui_gtk_load_config(); - } - else + if(splash_w != -1) { // the main window peeks out behind the splash screen so we reduce the dimensions if(splash_h > 100 && splash_w > 100) { - splash_x += 20; - splash_y += 50; - splash_w -= 100; - splash_h -= 100; + splash_x += 30; + splash_y += 40; + splash_w -= 60; + splash_h -= 80; } gtk_window_move(GTK_WINDOW(dt_ui_main_window(gui->ui)), splash_x, splash_y); gtk_window_resize(GTK_WINDOW(dt_ui_main_window(gui->ui)), splash_w, splash_h); @@ -1787,16 +1782,33 @@ static void _init_widgets(dt_gui_gtk_t *gui) dt_gui_process_events(); // Showing everything, to ensure proper instantiation and initialization - // then we hide the scroll bars and popup messages again gtk_widget_show_all(dt_ui_main_window(gui->ui)); + // then we hide the scroll bars and popup messages again gtk_widget_set_visible(dt_ui_log_msg(gui->ui), FALSE); gtk_widget_set_visible(dt_ui_toast_msg(gui->ui), FALSE); gtk_widget_set_visible(gui->scrollbars.hscrollbar, FALSE); gtk_widget_set_visible(gui->scrollbars.vscrollbar, FALSE); - // raise the splash screen, so that the main window doesn't cover it - // this call also processes all pending GUI events, ensuring that - // everyting is properly set up before we return - darktable_splash_screen_raise(); + + if(splash_w == -1) + { + // no splash screen: use the previously-saved geometry; we'll be + // setting the window to this size later anyway, but this avoids + // having it jump around + // this call needs to come AFTER the window is realized with + // gtk_widget_show_all to avoid having the WM get out of sync with + // darktable, especially if the window is maximized or on a + // different display + dt_gui_gtk_load_config(); + // and now finally refresh the screen + dt_gui_process_events(); + } + else + { + // raise the splash screen, so that the main window doesn't cover it + // this call also processes all pending GUI events, ensuring that + // everyting is properly set up before we return + darktable_splash_screen_raise(); + } } static const dt_action_def_t _action_def_focus_tabs; From de3c16b657961d7cecf00c8ad2cb246183391e4a Mon Sep 17 00:00:00 2001 From: ralfbrown Date: Sat, 18 Jan 2025 14:14:57 -0500 Subject: [PATCH 4/4] add more progress updates per dterrahe --- src/common/darktable.c | 2 ++ src/gui/gtk.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/darktable.c b/src/common/darktable.c index 037ef9adf8ae..24171e21f1e5 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -1818,10 +1818,12 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load if(init_gui) { + darktable_splash_screen_set_progress(_("loading utility modules")); darktable.lib = (dt_lib_t *)calloc(1, sizeof(dt_lib_t)); dt_lib_init(darktable.lib); // init the gui part of views + darktable_splash_screen_set_progress(_("loading views")); dt_view_manager_gui_init(darktable.view_manager); } diff --git a/src/gui/gtk.c b/src/gui/gtk.c index afb72cabb105..0b39b03aa5b9 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -775,8 +775,8 @@ int dt_gui_gtk_load_config() const gint x = MAX(0, dt_conf_get_int("ui_last/window_x")); const gint y = MAX(0, dt_conf_get_int("ui_last/window_y")); - gtk_window_resize(GTK_WINDOW(widget), width, height); gtk_window_move(GTK_WINDOW(widget), x, y); + gtk_window_resize(GTK_WINDOW(widget), width, height); const gboolean fullscreen = dt_conf_get_bool("ui_last/fullscreen"); if(fullscreen)