diff --git a/src/cli/main.c b/src/cli/main.c index e7a747c56bbf..bd46efa2b246 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -569,7 +569,7 @@ int main(int argc, char *arg[]) if(!g_file_test(fullname, G_FILE_TEST_IS_DIR) && dt_supported_image(fname)) { // Import each supported image file directly - const dt_imgid_t imgid = dt_image_import(filmid, fullname, TRUE, TRUE); + const dt_imgid_t imgid = dt_image_import(filmid, fullname, TRUE, FALSE); if(dt_is_valid_imgid(imgid)) { id_list = g_list_append(id_list, GINT_TO_POINTER(imgid)); @@ -598,7 +598,7 @@ int main(int argc, char *arg[]) gchar *directory = g_path_get_dirname(input); filmid = dt_film_new(&film, directory); - const dt_imgid_t id = dt_image_import(filmid, input, TRUE, TRUE); + const dt_imgid_t id = dt_image_import(filmid, input, TRUE, FALSE); g_free(directory); if(!dt_is_valid_imgid(id)) { diff --git a/src/common/darktable.c b/src/common/darktable.c index 9a48b38bc72d..bdd7f7d34260 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -1699,7 +1699,6 @@ int dt_init(int argc, gchar *styledir = g_build_filename(sharedir, "darktable/styles", NULL); if(styledir) { - dt_gui_process_events(); darktable_splash_screen_set_progress(_("importing default styles")); dt_import_default_styles(styledir); g_free(styledir); @@ -1861,6 +1860,9 @@ int dt_init(int argc, darktable.camctl = dt_camctl_new(); #endif + darktable.develop = malloc(sizeof(dt_develop_t)); + dt_dev_init(darktable.develop, TRUE); + // The GUI must be initialized before the views, because the init() // functions of the views depend on darktable.control->accels_* to // register their keyboard accelerators @@ -1881,26 +1883,16 @@ int dt_init(int argc, !dt_gimpmode() && dt_get_num_threads() >= 4 && !(dbfilename_from_command && !strcmp(dbfilename_from_command, ":memory:")); + } else darktable.gui = NULL; - darktable.view_manager = (dt_view_manager_t *)calloc(1, sizeof(dt_view_manager_t)); - dt_view_manager_init(darktable.view_manager); - - // check whether we were able to load darkroom view. if we failed, - // we'll crash everywhere later on. - if(!darktable.develop) - { - dt_print(DT_DEBUG_ALWAYS, "[dt_init] ERROR: can't init develop system, aborting."); - darktable_splash_screen_destroy(); - return 1; - } - - darktable_splash_screen_set_progress(_("loading processing modules")); + darktable_splash_screen_set_progress(_("loading image formats")); darktable.imageio = (dt_imageio_t *)calloc(1, sizeof(dt_imageio_t)); dt_imageio_init(darktable.imageio); + darktable_splash_screen_set_progress(_("loading processing modules")); // load default iop order darktable.iop_order_list = dt_ioppr_get_iop_order_list(0, FALSE); // load iop order rules @@ -1932,20 +1924,18 @@ int dt_init(int argc, if(init_gui) { + darktable_splash_screen_set_progress(_("loading views")); + darktable.view_manager = (dt_view_manager_t *)calloc(1, sizeof(dt_view_manager_t)); + dt_view_manager_init(darktable.view_manager); + 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); } /* 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); #endif @@ -1974,9 +1964,7 @@ int dt_init(int argc, if(argc == 2 && !_is_directory(argv[1])) { // If only one image is listed, attempt to load it in darkroom -#ifndef USE_LUA // may cause UI hang since after LUA init darktable_splash_screen_set_progress(_("importing image")); -#endif dt_load_from_string(argv[1], TRUE, NULL); } else if(argc >= 2) @@ -2005,16 +1993,26 @@ int dt_init(int argc, dt_conf_set_int("performance_configuration_version_completed", DT_CURRENT_PERFORMANCE_CONFIGURE_VERSION); } + + if(changed_xmp_files) + { + // construct the popup that asks the user how to handle images whose xmp + // files are newer than the db entry + dt_control_crawler_show_image_list(changed_xmp_files); + } } - } - free(config_info); - if(init_gui && !dt_gimpmode() && changed_xmp_files) - { - // construct the popup that asks the user how to handle images whose xmp - // files are newer than the db entry - dt_control_crawler_show_image_list(changed_xmp_files); + // show the main window and restore its geometry to that saved in the config file + gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui)); + dt_gui_gtk_load_config(); + dt_gui_process_events(); + darktable_splash_screen_destroy(); + + // finally set the cursor to be the default. + // for some reason this is needed on some systems to pick up the correctly themed cursor + dt_control_change_cursor(GDK_LEFT_PTR); } + free(config_info); // fire up a background job to perform sidecar writes dt_control_sidecar_synch_start(); @@ -2029,18 +2027,6 @@ int dt_init(int argc, dt_capabilities_add("nonapple"); #endif - if(init_gui) - { - // show the main window and restore its geometry to that saved in the config file - gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui)); - dt_gui_gtk_load_config(); - darktable_splash_screen_destroy(); - - // finally set the cursor to be the default. - // for some reason this is needed on some systems to pick up the correctly themed cursor - dt_control_change_cursor(GDK_LEFT_PTR); - } - dt_print(DT_DEBUG_CONTROL, "[dt_init] startup took %f seconds", dt_get_wtime() - start_wtime); diff --git a/src/control/signal.c b/src/control/signal.c index 18884ca2635b..8bfcdf2a6e5a 100644 --- a/src/control/signal.c +++ b/src/control/signal.c @@ -270,6 +270,7 @@ typedef struct async_com_data GCond end_cond; GMutex end_mutex; gpointer user_data; + gboolean finished; } async_com_data; gboolean _async_com_callback(gpointer data) @@ -278,6 +279,7 @@ gboolean _async_com_callback(gpointer data) g_mutex_lock(&communication->end_mutex); _signal_raise(communication->user_data); + communication->finished = TRUE; g_cond_signal(&communication->end_cond); g_mutex_unlock(&communication->end_mutex); return G_SOURCE_REMOVE; @@ -376,13 +378,14 @@ void dt_control_signal_raise(const dt_control_signal_t *ctlsig, dt_signal_t sign } else { - async_com_data communication; + async_com_data communication = {}; g_mutex_init(&communication.end_mutex); g_cond_init(&communication.end_cond); - g_mutex_lock(&communication.end_mutex); communication.user_data = params; g_main_context_invoke_full(NULL,G_PRIORITY_HIGH_IDLE, _async_com_callback,&communication, NULL); - g_cond_wait(&communication.end_cond,&communication.end_mutex); + g_mutex_lock(&communication.end_mutex); + while(!communication.finished) + g_cond_wait(&communication.end_cond,&communication.end_mutex); g_mutex_unlock(&communication.end_mutex); g_mutex_clear(&communication.end_mutex); } diff --git a/src/develop/develop.c b/src/develop/develop.c index 376d3d90e9eb..f4a8f91a73ec 100644 --- a/src/develop/develop.c +++ b/src/develop/develop.c @@ -106,14 +106,6 @@ void dt_dev_init(dt_develop_t *dev, dev->histogram_pre_levels_max = -1; dev->darkroom_mouse_in_center_area = FALSE; dev->darkroom_skip_mouse_events = FALSE; - - if(darktable.gui) - { - dev->full.ppd = darktable.gui->ppd; - dev->full.dpi = darktable.gui->dpi; - dev->full.dpi_factor = darktable.gui->dpi_factor; - dev->full.widget = dt_ui_center(darktable.gui->ui); - } } dev->iop_instance = 0; diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 7816660a01d8..02785283389d 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -4541,7 +4541,6 @@ void dt_gui_cursor_clear_busy() GtkWidget *toplevel = darktable.gui->ui->main_window; GdkWindow *window = gtk_widget_get_window(toplevel); gdk_window_set_cursor(window, busy_prev_cursor); - dt_gui_process_events(); g_object_unref(busy_prev_cursor); busy_prev_cursor = NULL; dt_control_allow_change_cursor(); @@ -4554,7 +4553,7 @@ void dt_gui_process_events() { // process pending Gtk/GDK events; we need to limit the total calls because once the LUA // interpreeter starts the script installer we would end up in an infinite loop - unsigned max_iter = 200; + unsigned max_iter = 1000; while(g_main_context_iteration(NULL, FALSE) && --max_iter > 0) continue; } diff --git a/src/imageio/imageio_module.c b/src/imageio/imageio_module.c index 8674e41fcb0e..ba43503cb1e1 100644 --- a/src/imageio/imageio_module.c +++ b/src/imageio/imageio_module.c @@ -162,9 +162,12 @@ static int dt_imageio_load_modules_format(dt_imageio_t *iio) continue; } module->gui_data = NULL; - if(darktable.gui) ++darktable.gui->reset; - module->gui_init(module); - if(darktable.gui) --darktable.gui->reset; + if(darktable.gui) + { + ++darktable.gui->reset; + module->gui_init(module); + --darktable.gui->reset; + } if(module->widget) g_object_ref(module->widget); g_free(libname); res = g_list_insert_sorted(res, module, dt_imageio_sort_modules_format); diff --git a/src/libs/tools/module_toolbox.c b/src/libs/tools/module_toolbox.c index d1c87895b820..3ec0d9a15120 100644 --- a/src/libs/tools/module_toolbox.c +++ b/src/libs/tools/module_toolbox.c @@ -24,25 +24,6 @@ DT_MODULE(1) -/* proxy function, to add a widget to toolbox */ -static void _lib_module_toolbox_add(dt_lib_module_t *self, - GtkWidget *widget, - dt_view_type_flags_t views); - - -typedef struct child_data_t -{ - GtkWidget * child; - dt_view_type_flags_t views; - -} child_data_t; - -typedef struct dt_lib_module_toolbox_t -{ - GtkWidget *container; - GList * child_views; -} dt_lib_module_toolbox_t; - const char *name(dt_lib_module_t *self) { return _("module toolbox"); @@ -71,60 +52,12 @@ int position(const dt_lib_module_t *self) void gui_init(dt_lib_module_t *self) { - /* initialize ui widgets */ - dt_lib_module_toolbox_t *d = g_malloc0(sizeof(dt_lib_module_toolbox_t)); - self->data = (void *)d; - /* the toolbar container */ - d->container = self->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - - /* setup proxy */ - darktable.view_manager->proxy.module_toolbox.module = self; - darktable.view_manager->proxy.module_toolbox.add = _lib_module_toolbox_add; + self->widget = darktable.view_manager->module_toolbox; } void gui_cleanup(dt_lib_module_t *self) { - dt_lib_module_toolbox_t *d = self->data; - g_list_free_full(d->child_views,free); - g_free(self->data); - self->data = NULL; -} - -void view_enter(dt_lib_module_t *self, - dt_view_t *old_view, - dt_view_t *new_view) -{ - dt_lib_module_toolbox_t *d = self->data; - dt_view_type_flags_t nv= new_view->view(new_view); - gtk_widget_set_no_show_all(d->container, TRUE); - for(const GList *child_elt = d->child_views; child_elt; child_elt = g_list_next(child_elt)) - { - child_data_t* child_data = child_elt->data; - if(child_data->views & nv) - { - gtk_widget_show_all(child_data->child); - } - else - { - gtk_widget_hide(child_data->child); - } - } -} - -static void _lib_module_toolbox_add(dt_lib_module_t *self, - GtkWidget *widget, - dt_view_type_flags_t views) -{ - dt_lib_module_toolbox_t *d = self->data; - gtk_box_pack_start(GTK_BOX(d->container), widget, TRUE, FALSE, 0); - gtk_widget_show_all(widget); - - child_data_t *child_data = malloc(sizeof(child_data_t)); - child_data->child = widget; - child_data->views = views; - d->child_views = g_list_prepend(d->child_views,child_data); - } // clang-format off // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py diff --git a/src/libs/tools/view_toolbox.c b/src/libs/tools/view_toolbox.c index 57e7f0a1a42c..cb975c8fd128 100644 --- a/src/libs/tools/view_toolbox.c +++ b/src/libs/tools/view_toolbox.c @@ -24,25 +24,6 @@ DT_MODULE(1) -/* proxy function, to add a widget to toolbox */ -static void _lib_view_toolbox_add(dt_lib_module_t *self, - GtkWidget *widget, - dt_view_type_flags_t views); - - -typedef struct child_data_t -{ - GtkWidget * child; - dt_view_type_flags_t views; - -} child_data_t; - -typedef struct dt_lib_view_toolbox_t -{ - GtkWidget *container; - GList * child_views; -} dt_lib_view_toolbox_t; - const char *name(dt_lib_module_t *self) { return _("view toolbox"); @@ -70,64 +51,12 @@ int position(const dt_lib_module_t *self) void gui_init(dt_lib_module_t *self) { - /* initialize ui widgets */ - dt_lib_view_toolbox_t *d = g_malloc0(sizeof(dt_lib_view_toolbox_t)); - self->data = (void *)d; - /* the toolbar container */ - d->container = self->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - - /* setup proxy */ - darktable.view_manager->proxy.view_toolbox.module = self; - darktable.view_manager->proxy.view_toolbox.add = _lib_view_toolbox_add; + self->widget = darktable.view_manager->view_toolbox; } void gui_cleanup(dt_lib_module_t *self) { - dt_lib_view_toolbox_t *d = self->data; - g_list_free_full(d->child_views,free); - g_free(self->data); - self->data = NULL; -} - -void view_enter(dt_lib_module_t *self, - dt_view_t *old_view, - dt_view_t *new_view) -{ - dt_lib_view_toolbox_t *d = self->data; - dt_view_type_flags_t nv= new_view->view(new_view); - gtk_widget_set_no_show_all(d->container, TRUE); - - for(const GList *child_elt = d->child_views; - child_elt; - child_elt = g_list_next(child_elt)) - { - child_data_t* child_data = child_elt->data; - if(child_data->views & nv) - { - gtk_widget_show_all(child_data->child); - } - else - { - gtk_widget_hide(child_data->child); - } - } -} - - -static void _lib_view_toolbox_add(dt_lib_module_t *self, - GtkWidget *widget, - dt_view_type_flags_t views) -{ - dt_lib_view_toolbox_t *d = self->data; - gtk_box_pack_start(GTK_BOX(d->container), widget, TRUE, FALSE, 0); - gtk_widget_show_all(widget); - - child_data_t *child_data = malloc(sizeof(child_data_t)); - child_data->child = widget; - child_data->views = views; - d->child_views = g_list_prepend(d->child_views,child_data); - } // clang-format off // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py diff --git a/src/lua/call.c b/src/lua/call.c index 3ea1b71ef398..616ac12feabe 100644 --- a/src/lua/call.c +++ b/src/lua/call.c @@ -658,13 +658,15 @@ static int gtk_wrap(lua_State*L) lua_tostring(L, lua_upvalueindex(2)), lua_tointeger(L, lua_upvalueindex(3))); #endif dt_lua_unlock(); - gtk_wrap_communication communication; + gtk_wrap_communication communication = {}; g_mutex_init(&communication.end_mutex); g_cond_init(&communication.end_cond); communication.L = L; - g_mutex_lock(&communication.end_mutex); + communication.retval = -1; g_main_context_invoke_full(NULL,G_PRIORITY_HIGH_IDLE, dt_lua_gtk_wrap_callback,&communication, NULL); - g_cond_wait(&communication.end_cond,&communication.end_mutex); + g_mutex_lock(&communication.end_mutex); + while(communication.retval == -1) + g_cond_wait(&communication.end_cond,&communication.end_mutex); g_mutex_unlock(&communication.end_mutex); g_mutex_clear(&communication.end_mutex); dt_lua_lock(); diff --git a/src/views/darkroom.c b/src/views/darkroom.c index 79024b965534..06a9bfa8cde2 100644 --- a/src/views/darkroom.c +++ b/src/views/darkroom.c @@ -152,11 +152,7 @@ static void _get_zoom_pos_bnd(dt_dev_viewport_t *port, void init(dt_view_t *self) { - dt_develop_t *dev = malloc(sizeof(dt_develop_t)); - self->data = darktable.develop = dev; - - dt_dev_init(dev, TRUE); - + self->data = darktable.develop; darktable.view_manager->proxy.darkroom.view = self; #ifdef USE_LUA @@ -2444,6 +2440,10 @@ void connect_button_press_release(GtkWidget *w, GtkWidget *p) void gui_init(dt_view_t *self) { dt_develop_t *dev = self->data; + dev->full.ppd = darktable.gui->ppd; + dev->full.dpi = darktable.gui->dpi; + dev->full.dpi_factor = darktable.gui->dpi_factor; + dev->full.widget = dt_ui_center(darktable.gui->ui); dt_action_t *sa = &self->actions, *ac = NULL; diff --git a/src/views/view.c b/src/views/view.c index 9c8a8a271640..545a6a50c769 100644 --- a/src/views/view.c +++ b/src/views/view.c @@ -85,21 +85,15 @@ void dt_view_manager_init(dt_view_manager_t *vm) " AND id != ?2", -1, &vm->statements.get_grouped, NULL); + vm->module_toolbox = dt_gui_hbox(); + vm->view_toolbox = dt_gui_hbox(); + dt_view_manager_load_modules(vm); vm->current_view = NULL; vm->audio.audio_player_id = -1; } -void dt_view_manager_gui_init(dt_view_manager_t *vm) -{ - for(GList *iter = vm->views; iter; iter = g_list_next(iter)) - { - dt_view_t *view = iter->data; - if(view->gui_init) view->gui_init(view); - } -} - void dt_view_manager_cleanup(dt_view_manager_t *vm) { for(GList *iter = vm->views; @@ -187,6 +181,7 @@ static int dt_view_load_module(void *v, module->module_name, module->name(module) }; dt_action_insert_sorted(&darktable.control->actions_views, &module->actions); + if(module->gui_init) module->gui_init(module); } return 0; @@ -202,9 +197,12 @@ static void dt_view_unload_module(dt_view_t *view) g_module_close(view->module); } -void dt_vm_remove_child(GtkWidget *widget, gpointer data) +static void _show_hide_toolbox_widget(GtkWidget *widget, + gpointer data) { - gtk_container_remove(GTK_CONTAINER(data), widget); + gtk_widget_set_no_show_all(widget, TRUE); + gtk_widget_set_visible(widget, + GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "views")) & GPOINTER_TO_INT(data)); } gboolean dt_view_manager_switch(dt_view_manager_t *vm, @@ -307,13 +305,11 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, // show we are busy changing views dt_control_change_cursor(GDK_WATCH); + gdk_display_sync(gdk_display_get_default()); /* cleanup current view before initialization of new */ if(old_view) { - if(new_view != old_view) - dt_gui_process_events(); - /* leave current view */ if(new_view != old_view && old_view->leave) old_view->leave(old_view); @@ -408,8 +404,9 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, if(!strcmp(plugin->plugin_name,"module_toolbox") || !strcmp(plugin->plugin_name,"view_toolbox")) { + gtk_container_foreach(GTK_CONTAINER(w), _show_hide_toolbox_widget, GINT_TO_POINTER(view_type)); if(view_type == DT_VIEW_LIGHTTABLE) - dt_gui_add_help_link(w, "lighttable_mode"); + dt_gui_add_help_link(w, "lighttable_mode"); if(view_type == DT_VIEW_DARKROOM) dt_gui_add_help_link(w, "darkroom_bottom_panel"); } @@ -1112,16 +1109,16 @@ void dt_view_manager_view_toolbox_add(dt_view_manager_t *vm, GtkWidget *tool, const dt_view_type_flags_t views) { - if(vm->proxy.view_toolbox.module) - vm->proxy.view_toolbox.add(vm->proxy.view_toolbox.module, tool, views); + g_object_set_data(G_OBJECT(tool), "views", GINT_TO_POINTER(views)); + dt_gui_box_add(vm->view_toolbox, tool); } void dt_view_manager_module_toolbox_add(dt_view_manager_t *vm, GtkWidget *tool, const dt_view_type_flags_t views) { - if(vm->proxy.module_toolbox.module) - vm->proxy.module_toolbox.add(vm->proxy.module_toolbox.module, tool, views); + g_object_set_data(G_OBJECT(tool), "views", GINT_TO_POINTER(views)); + dt_gui_box_add(vm->module_toolbox, tool); } dt_darkroom_layout_t dt_view_darkroom_get_layout(const dt_view_manager_t *vm) diff --git a/src/views/view.h b/src/views/view.h index 7bdd82d1ddbd..410038fd2913 100644 --- a/src/views/view.h +++ b/src/views/view.h @@ -248,26 +248,14 @@ typedef struct dt_view_manager_t // toggle button for guides (in the module toolbox) GtkWidget *guides_toggle, *guides, *guides_colors, *guides_contrast, *guides_popover; + // toolbox containers + GtkWidget *module_toolbox, *view_toolbox; + /* * Proxy */ struct { - - /* view toolbox proxy object */ - struct - { - struct dt_lib_module_t *module; - void (*add)(struct dt_lib_module_t *, GtkWidget *, dt_view_type_flags_t ); - } view_toolbox; - - /* module toolbox proxy object */ - struct - { - struct dt_lib_module_t *module; - void (*add)(struct dt_lib_module_t *, GtkWidget *, dt_view_type_flags_t); - } module_toolbox; - /* filter toolbox proxy object */ struct { @@ -417,7 +405,6 @@ typedef struct dt_view_manager_t } dt_view_manager_t; void dt_view_manager_init(dt_view_manager_t *vm); -void dt_view_manager_gui_init(dt_view_manager_t *vm); void dt_view_manager_cleanup(dt_view_manager_t *vm); /** return translated name. */