Add GimpMenuFactory can always be found in a GimpDialogManager, use
gimp_dialog_factory_get_menu_factory() where we have a dialog factory
instead of accessing "global_menu_factory" or redundantly passing a
menu factory around where we already pass around a dialog factory.
...after entering single window mode
This commit fixes dangling pointers in GimpDockColumns, it doesn't fix
the bug but it's a prerequisite. Original patch by Massimo.
Instead, either destroy the child instead of removing it, or remove
*and* destroy it in cases where the remove() api on the "parent"
doesn't match GTK+'s parent/child relation (like with all our dock
widgets). We can't rely on remove() to implicitly detstroy, because
there might be arbitrary other code holding references, such as
accessibility modules and whatnot. Most likely fixes unclear crashes
in accessibility code and other crashes we blamed GTK+ for.
Instead, inherit from GtkBox directly and set the orientation in
init(). Replace more gtk_container_add() by gtk_box_pack_start() in
the reparented classes.
Only remove a dock in the book-removed callback to dock columns if the
dock has the dock column as parent. It won't during destruction for
example. This fixes the test case
/gimp-ui/restore-recently-closed-multi-column-dock.
Instead of including dialogs/dialogs.h everywhere, introduce
gimp_dialog_factory_get_singleton(). The dialog factory singleton is
still initialized by dialogs.c though.
Right now the assumption is that we never will have another dialog
factory instance around. There were so many problems before when we
had four of them, so let's just keep one of them around.
Add "dialog-factory", "ui-manager" properties to GimpDockColumns and
let GimpDock look for these before trying to look for a dock window
which does not exist in single-window mode.
Add and use gimp_dock_columns_new() and add a GimpContext property to
GimpDockColumns. Also move the widget construction from _init() to
_constructor() in GimpDockWindow so we have a context object to pass
to gimp_dock_columns_new().
When moving dockables from a dock window to an image window, they need
to start listening to the user context. So update the dockables with
the new context when we switch window mode.
In order to make a GimpDock get hold of a GimpContext both in
single-window mode and in multi-window mode, don't make it look for a
GimpContext in a GimpDockWindow, put the context in GimpDockColumns
instead. GimpDockColumns exists both in s-w-m and m-w-m, contrary to
GimpDockWindow. Still use the GimpDockWindow as a backup though.
Don't crash when detaching dockables from the image window. This
scenario only occurs in single-window mode. We solve it by using
global variables and checking for NULL for src_dock_window; there is
no dock window when detaching from the image window.
The use of global variables is meant to be temporary.
Move the Image Selection Menu from GimpMenuDock to
GimpDockWindow. That is, if a dock window contains many docks then
they will share the same Image Selection Menu.
To do this we need to move around quite a bit of code. Move the
"context", "dialog-factory" and "ui-manager" properties from GimpDock
to GimpToolbox, GimpMenuDock doesn't need it any longer. Turn the
GimpDock getters for these properties into wrappers that go to the
GimpDockWindow properties. In some places, most notably GimpToolbox
construction, we use the GimpToolbox values of these properties, but
most of the time it works fine to just use the GimpDockWindow
properties. GimpDock::setup() and set/get_aux_info() have also been
moved to GimpDockWindow since the only aux info for docks was for the
image selection menu.
Also, we don't bother porting gimp_menu_dock_destroy() to
GimpDockWindow, but we leave the code around. If this is a problem, it
will show.
Make drag-and-drop rearrangement of dockables happen directly in the
existing widget hierarchy so we don't have to use special, ugly
widgets (read GimpDockSeparator:s) for that.
More specifically, make edges of dockables and dockbooks have the same
semantics as the GimpDockSeparators had. We put a highlight colored
GdkWindow on top of the widget in question to highlight these special
drop areas. This GdkWindow is not taken into consideration in the GTK+
drag-and-drop code, so it does not interupt the DND interaction.
To achive this, there is a problem we must solve: Drag events in GTK+
are propagated inwards and out, but we sometimes want ancenstor
widgets to take care of drop events. We solve this by introducing the
concept of "drag handlers". A drag handler is asked if it will handle
a given drag event, and if it will, a client will let the drag event
be propagated upwards in the widget hierarchy. Right now, the
GimpPanedBox is the only "drag handler". The code could be generalized
more but it doesn't feel worth it at this point.
The size of the special drop area is 5px, the same size as the default
GtkPaned handles. This is because the plan is to later use these
handles as drop areas too.
Other changes of interest are:
* We need to take care of "drag-motion", "drag-drop" and widget
highlightning ourselves. We can not use the GtkDestDefaults
conveniences with gtk_drag_dest_set() any longer since we need more
control.
* Make the drop callback pass the insert index directly instead of a
GimpDockSeparator
* Add some GIMP_LOG() debug output for DND
* Disable the GimpDockSeparator code in GimpToolbox
Move g_list_copy() out from gimp_dock_columns_get_docks(). Fixes at
least one memory leak (in gimp_dock_window_get_dock()) and feels nicer
and more flexible.
When dropping a dockable on a dock separator on the side of e.g. a
dock window, a new column of dockables will be created. This allows
multi-column dock window setups.