Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

splash screen without forced keep-above #18236

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions src/common/darktable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,11 @@ 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();
dt_gui_process_events(); // ensure that the splash screen is removed right away
}
}
}

Expand Down Expand Up @@ -1813,26 +1818,20 @@ 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);

// 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(_(""));
Expand Down Expand Up @@ -1911,8 +1910,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();
}
Expand All @@ -1930,10 +1927,11 @@ 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)));
// unhide the main window and restore its geometry to that saved in the config file
dt_gui_gtk_load_config();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If done in this order, I get, on windows

  • splash screen disappears
  • 1 second nothing
  • window opens in old location
  • window maximizes or goes full screen

if instead I do

    // unhide the main window and restore its geometry to that saved in the config file
    dt_gui_gtk_load_config();
    gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui));
    darktable_splash_screen_destroy();

then the splash screen is instantaneously replaced by the window in its final location.
The gtk_widget_show_all and gtk_widget_set_visible(FALSE) (=hide) in _init_widgets is not needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the gtk_widget_show_all from _init_widgets restults in half a dozen assertion failure messages from Gdk, because various items in the main window haven't been realized yet (they don't get created until the main window is initially shown).

Copy link
Member

@dterrahe dterrahe Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make the code more robust by adding the appropriate checks rather than implementing more workarounds?

dterrahe@40fce3c generates no warnings for me, on debian (x&wayland, under WSL2) and windows.

Unfortunately, if dt_gui_gtk_load_config is moved before show_all, when restoring a maximized state, the application thinks it is maximized, but the window manager disagrees. Even if dt_gui_gtk_load_config is executed both before and after show_all (presumably for an "already maximized" window, maximize is a noop). So there is still a very minimal/undiscernible amount of flashing when showing the screen. But no second or so gap between the splash disappearing and the main window appearing and also no overlap.

EDIT: if you still do see assertions, please let me know which so I can look into them.

darktable_splash_screen_destroy();
}

dt_print(DT_DEBUG_CONTROL,
Expand Down
48 changes: 23 additions & 25 deletions src/gui/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -1766,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);
Expand All @@ -1788,29 +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
// 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));
ralfbrown marked this conversation as resolved.
Show resolved Hide resolved
// 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);

// 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...

// finally, process all accumulated GUI events so that everything is properly
// set up before proceeding
for(int i = 0; i < 5; i++)
if(splash_w == -1)
{
g_usleep(500);
// 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;
Expand Down
12 changes: 10 additions & 2 deletions src/gui/splash.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -307,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)
Expand Down
1 change: 1 addition & 0 deletions src/gui/splash.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading