Brush, font, gradient, palette and pattern choices are currently chosen through
a dialog created by the core, which then returns the user choice to the calling
plug-in. This has the unfortunate consequence of having a pile of likely at
least 3 windows (main GIMP window by core process, plug-in window by plug-in
process, then the choice popup by the core process) shared in 2 processes, which
often end up under each other and that's messy. Even more as the choice popup is
kinda expected to be like a sub-part of the plug-in dialog.
So anyway, now the plug-in can send its window handle to the core so that the
resource choice dialog ends up always above the plug-in dialog.
Of course, it will always work only on platforms where we have working
inter-process transient support.
Having windows ID as guint32 is a mistake. Different systems have
different protocols. In Wayland in particular, Windows handles are
exchanged as strings. What this commit does is the following:
In core:
- get_window_id() virtual function in core GimpProgress is changed to
return a GBytes, as a generic "data" to represent a window differently
on different systems.
- All implementations of get_window_id() in various classes implementing
this interface are updated accordingly:
* GimpSubProgress
* GimpDisplay returns the handle of its shell.
* GimpDisplayShell now creates its window handle at construction with
libgimpwidget's gimp_widget_set_native_handle() and simply return
this handle every time it's requested.
* GimpFileDialog also creates its window handle at construction with
gimp_widget_set_native_handle().
- gimp_window_set_transient_for() in core is changed to take a
GimpProgress as argument (instead of a guint32 ID), requests and
process the ID itself, according to the running platform. In
particular, the following were improved:
* Unlike old code, it will work even if the window is not visible yet.
In such a case, the function simply adds a signal handler to set
transient at mapping. It makes it easier to use it at construction
in a reliable way.
* It now works for Wayland too, additionally to X11.
- GimpPdbProgress now exchanges a GBytes too with the command
GIMP_PROGRESS_COMMAND_GET_WINDOW.
- display_get_window_id() in gimp-gui.h also returns a GBytes now.
PDB/libgimp:
- gimp_display_get_window_handle() and gimp_progress_get_window_handle()
now return a GBytes to represent a window handle in an opaque way
(depending on the running platform).
In libgimp:
- GimpProgress's get_window() virtual function changed to return a
GBytes and renamed get_window_handle().
- In particular GimpProgressBar is the only implementation of
get_window_handle(). It creates its handle at object construction with
libgimpwidget's gimp_widget_set_native_handle() and the virtual
method's implementation simply returns the GBytes.
In libgimpUi:
- gimp_ui_get_display_window() and gimp_ui_get_progress_window() were
removed. We should not assume anymore that it is possible to create a
GdkWindow to be used. For instance this is not possible with Wayland
which has its own way to set a window transient with a string handle.
- gimp_window_set_transient_for_display() and
gimp_window_set_transient() now use an internal implementation similar
to core gimp_window_set_transient_for(), with the same improvements
(works even at construction when the window is not visible yet + works
for Wayland too).
In libgimpwidgets:
- New gimp_widget_set_native_handle() is a helper function used both in
core and libgimp* libraries for widgets which we want to be usable as
possible parents. It takes care of getting the relevant window handle
(depending on the running platform) and stores it in a given pointer,
either immediately or after a callback once the widget is mapped. So
it can be used at construction. Also it sets a handle for X11 or
Wayland.
In plug-ins:
- Screenshot uses the new gimp_progress_get_window_handle() directly now
in its X11 code path and creates out of it a GdkWindows itself with
gdk_x11_window_foreign_new_for_display().
Our inter-process transient implementation only worked for X11, and with
this commit, it works for Wayland too.
There is code for Windows but it is currently disabled as it apparently
hangs (there is a comment in-code which links to this old report:
https://bugzilla.gnome.org/show_bug.cgi?id=359538). NikcDC tested
yesterday with re-enabling the code and said they experienced a freeze.
;-(
Finally there is no infrastructure yet to make this work on macOS and
apparently there is no implementation of window handle in GDK for macOS
that I could find. I'm not sure if macOS doesn't have this concept of
setting transient on another processus's window or GDK is simply lacking
the implementation.
Though GTK+3 is supposed to take care of scaling fonts with high density
displays, it turns out it is not enough for many, for various reasons (taste,
eyesight, distance to the display…). So we add this additional settings to tweak
further the font size.
With Aryeom, we experimented/discussed both a percentage UI vs. an absolute font
size field (e.g. as they provide in GNOME Tweaks). In the end, we went for a
percentage UI because we realize that we don't necessarily know what is the
current size at all. Mostly you just want bigger or smaller, and don't
necessarily care so much at which value is the font size.
This settings only has a single limitation (that we could find), which is when
used on a theme with widget rules using absolute font-size rules (px, or
keywords such as small/medium/large). As long as the CSS rules are relative
though (either to the parent widget, or to the root size), then it works fine.
Basically a theme hard-coding font sizes won't fare well with this settings, but
since we can consider this bad practice, it's an acceptable limitation.
This is not the main reason for the specific output in #9994. These ones are
more probably because of similar usage in GTK (which updated its own calls to
g_file_info_get_is_hidden|backup() in version 3.24.38). But we should likely
also update the various calls we have to use the generic
g_file_info_get_attribute_*() variants.
To be fair, it is unclear to me when we can be sure that an attribute is set.
For instance, when we call g_file_enumerate_children() or g_file_query_info()
with specific attributes, docs say that it is still possible for these
attributes to not be set. So I assume it means we should never use direct
accessor functions.
The only exception is that I didn't remove usage of g_file_info_get_name(),
since its docs says:
> * Gets a display name for a file. This is guaranteed to always be set.
Even though it also says just after:
> * It is an error to call this if the #GFileInfo does not contain
> * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME.
Which is very contradictory. But assuming that this error warning was
over-zealous documentation, I kept the direct accessors since they are supposed
to be slightly more optimized (still according to in-code documentation) so
let's priorize them when we know they are set for sure.
My previous commit was improving the case where we just get many "dirty" signals
and successful inhibition. But if the inhibition request was failing, we would
just retry again and again.
This new version will hold off on on requesting the inhibition for the next 10
minutes. Then it will try again, in case the failure reason might have been
temporary.
… the reason message changes (i.e. when number of dirty image changes).
Some actions in particular would trigger several "dirty" signals, there is no
reason to uninhibit then re-inhibit repeatedly. And as a more general rule,
there is no reason to do so even for different actions while we are not planning
to update the inhibition reason.
It may not be the main reason for #9446 (because if it hangs for several
minutes, there is likely something going on, deeper at the dbus call level), yet
it would definitely alleviate the issue (dividing the wait by as many times as
the dirty signal was emitted!).
When passing an application ID (which is necessary for application inhibition to
work, i.e. logoff/reboot/shutdown inhibition), GApplication will try to ensure
process uniqueness, which will trigger a new activation to an already running
process. Since our current code assumes that the application can be activated a
single time only, this was what was triggering a whole lot of errors (on the
first running process) in #9598 because there was all the initialization code
which ran again, whereas it was not supposed to.
This doubly-running initialization code was also what completely messed up the
session files, hence broke the GUI after a restart (#9599).
Therefore passing G_APPLICATION_NON_UNIQUE advertizes we don't want GIO to
handle process uniqueness for us.
Note that this is actually a very interesting feature which we have had in GIMP
codebase forever. It would be interesting to kill all our own uniqueness code in
favor of GIO code (and let them handle/maintain passing command line arguments
from one process to another, for all possible platforms). So I added a TODO for
this (for now, we just ignore this feature as it doesn't work well with current
codebase).
Resolves#5742.
From fa0a0212, the splash's upper text was scaled to PANGO_SCALE_MEDIUM
both when the image width was 2x or less than 2x. This was likely a
copy/paste issue, as the lower text code scaling does not duplicate.
This patch fixes it by changing the else condition to scale to
PANGO_SCALE_SMALL.
Note that this change is unlikely to be seen as it requires a very small
splash screen image to reach the else condition.
gtk_accel_map_load()/gtk_accel_map_save() are not working with the new
GAction-based code. GtkApplication does not seem to have helper functions to
simply load and save accelerators in a file, so we just implement it ourselves.
A few things are missing right now, namely:
- On parsing, it doesn't handle any kind of duplicate accelerators (possible
especially if someone edited the new shortcutsrc manually).
- On reading, maybe we should only write down the changed (from defaults)
actions, while keeping the old ones commented-out, as menurc used to be. This
is actually useful info both for debugging or even for users who want to look
at this file and see what they changed.
- We should add import code to transform the menurc into shortcutsrc when
updating GIMP, otherwise all custom shortcuts would get lost.
There is still the question on whether we should add the group name too. I think
we should, expecially for plug-in's procedure actions, though right now these
are just added in the GtkApplication's main action group anyway. I'll see later
to refine this.
Pre-GIMP-3.0 code logics would re-allocate several GimpMenuFactory or
GimpUIManager for no good reason. While it was still working with old GtkAction
code, with our new GAction-based code, we were ending up overriding an action
with a new version of the same action, while keeping reference to old actions.
This made for discrepancies of the enabled or visible state of actions.
The new code keeps singleton of some objects and references to already
registered GimpUIManager or GimpActionGroups objects and make sure no actions
with the same name are created twice.
Unless mistaken, this is not needed anymore. New GtkApplication code should take
care of creating the native macOS application menu for us.
Cf. also contents of MR !558.
If we want to reuse this in subclasses, we'd need to overwrite finalize() in the
subclasses, call gimp_core_app_finalize() and chain up with the parent class.
Not doing this until now was leading us not to call GApplication or
GtkApplication finalize() function, which in turn, in the later case, was
leaking all the GAction-s which were added to the GActionMap. I realized this as
a leaking GimpContext-s warning was printing when ending GIMP.
I realize that UI_TEST is only used in our meson scripts and is therefore not a
reliable environment variable to check for whether we are running a unit test or
not. GIMP_TESTING_ABS_TOP_SRCDIR should be present for all unit testing, on both
build systems.
The real problem was not actuall logout-inhibition, but availability of the
GtkApplication. Anyway this feature is not really to block the system while
unit-testing but for saving people's actual work. Let's just disable running it
in test case.
This will fix the CI.
- app_activate_callback() moved with other private functions.
- Removing the `if (app)` test in app_activate_callback() as we don't
set it to NULL anymore. The app variable is always set.
- As a consequence of the previous point, change signature of
app_exit_after_callback() which doesn't have to change the value of
app anymore.
- Don't emit direcly the "exit" signal from app_activate_callback(). We
must call `gimp_exit (gimp, TRUE);` instead, which does more than just
emitting this signal. It also takes care of cleaning any remaining
images without a display. If we don't do this, we are leaking
GeglBuffer when opening images from command lines while quitting
immediately with --quit.
- Get rid of gimp_core_app_set_values() which was completely bypassing
the fact that all the properties of a GimpCoreApp were construct-only.
Instead make these proper properties. I use a trick used in other
interface, creating a gimp_container_view_install_properties() which
is called from child classes.
The point of GimpCoreApp is not just to share a common interface, it's
rather to weakly simulate some kind of multi-inheritance in GObject.
Since we want both GimpApp and GimpConsoleApp to inherit from a same
parent class while we also want them to inherit either from
GtkApplication and GApplication respectively (yet without linking to
GTK in this second case), we are stuck as far as normal GObject
inheritance goes. This is why we use an interface to which we add a
private struct through a GQuark trick. We want the property settings
and function implementations to also be part of this shared code.
- Get rid of all the abstract methods of GimpCoreApp of the form
get_*(). These are useless as we don't expect these to have different
implementation depending on the actual child class. Once again, our
main goal was to simulate multiple inheritance rather than actually
have an interface with various implementations.
- Make "no-splash" a property of GimpApp, because it's cleaner this way.
- Fix gimp_core_app_private_finalize().
- don't use #pragma once, it's not standard. Just use include guards.
- Fix includes: order was wrong, include from the source, not other
headers, etc.
- Clean various other details, coding styles, fix several more bugs and
more…
Reviewer's message (Jehan): This was a work-in-progress by Niels, which
we only keep in this state because Lukas worked over it. I have rebased
and fix-amended many broken part of this commit, because various things
had been changed in these areas of code since this commit was initially
written.
This kinda reverts commit 6aebd30de1 ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
This way, what will happen is that:
- We can have a single "Default" theme which will have both the light
and dark versions.
- With our Default theme, when "Use dark theme variant if available" is
unchecked, we just follow the system-wide dark settings. (though I'm
unsure we actually do with current code; we do load our theme over the
system theme, which may be dark, but I don't think we'd load a dark
theme variant then)
- If the option is checked, we will load the specific dark variant,
bypassing system settings specifically for GIMP.
Technically for theme designers, all it takes to have a dark variant is
to add a gimp-dark.css next to gimp.css. `gimp-dark.css` is loaded
instead of `gimp.css` when the settings is checked.
Note: there is apparently a new freedesktop portal for setting the
prefered variant (and now it's apparently either light, dark or
default), which is now implemented by GNOME, KDE and Elementary at
least. It would be nice if we could grab this settings and use it if
available. The below link has code sample showing how to do it with
DBus:
https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/Dark-Style-Preference
This object's goal will be to manage customized modifiers per input
device button, which is why I add it to GimpDisplayConfig. It is in its
own new config file (`modifiersrc` in config dir) because it requires
GDK types access (well I could have done without, but it would have been
less semantic, hence not as good of an API). Anyway it is only useful
when running GIMP as GUI.
The GUI widget and the usage code to make this actually useful will come
in upcoming commits.
Basically disabling commit 4f9b7373e6.
After some new patches for GTK3 I wrote, and removing the settings on
NSViewUsesAutomaticLayerBackingStores, Lukas reported that it works like
never before, faster than 2.10 even. Note that this could only be tested
on Monterey, nobody tested on Big Sur with this specific combination
yet.
In any case, we decided to remove this settings and add the new GTK3
patches.
See: https://gitlab.gnome.org/Infrastructure/gimp-macos-build/-/merge_requests/86#note_1384727
It's a bit ugly, but it's not like this is run many times (only once
when loading the icon theme, or changing it).
Fixes this error appearing in various unit tests' output:
> gimp_icons_sanity_check: Icon theme path has no 'hicolor' subdirectory: /builds/GNOME/gimp/_install/share/gimp/2.99/icons
(even though it was not a test-failure error, it's still better to limit
output for debugging)
When running tests, the data are not meant to be necessarily installed.
Therefore icons won't be found when calling gimp_widgets_init().
Add some special-casing to find them relatively to the install
directory.
Reviewer comment (Jehan): we have used this patch successfully on our
installers since start of 2021 (see commit b4d665d of our gtk-osx fork)
and it really improved the situation. I only fixed minor coding style
stuff in the patch.
Looking at what it does, I guess it is not ideal long-term if related to
10-bit display (as I understand from the comment), which a graphics app
would want to support properly. But for now, this is better than
extra-slow display until we get macOS developers able to look at this
more in depth in the future (I don't think that our dependencies are
really ready yet for 10-bit display support anyway, though I may be
wrong).
Some other forums seem to say it comes from macOS invalidating now more
than it should (i.e. the whole area instead of only the changed area)
and this NSViewUsesAutomaticLayerBackingStores flag would disable this
behavior. It might be one of these reasons, the other or both. This is
anyway a good first start for future contributors.
Simply it should free only GimpProgressDialog as these would be
dedicated dialog (with no meaning once progression is done), and leave
alone other GimpProgress widgets. In any case, it should not output
CRITICAL errors on these.
Fixing the following CRITICAL:
> GIMP-CRITICAL: gui_free_progress: assertion 'GIMP_IS_PROGRESS_DIALOG (progress)' failed
When dropping an image on the toolbox.
In some cases, error dialogs may end up below other windows and stay
unnoticed because of how dialogs are raised and hidden on various
platforms. This is not very constructive. It's much better to make sure
one sees an error when it happens (in some cases, it may mean possible
data loss, so it should be at least acknowledged; also seeing it later
may mean you can't know anymore which action triggered this error,
making the whole process kind of meaningless and hard to debug).
So anyway, let's make error messages prominent by having them always
above.
- Set the software as `initialized` later, and in particular after all
recovered images (from crash) then all command line images were
opened. The reason is that the DBus calls have necessarily been made
after GIMP was started (typically could be images double-clicked
through GUI). We don't want them to appear before the images given in
command line (or worse, some before and some after).
- Process DBus service's data queue as a FIFO. The image requested first
will be loaded first.
- When a DBus call happens while GIMP is not initialized or restored,
switch to a timeout handler. The problem with idle handlers is that
they would be attempted too often (probably even more during startup
when no user event happens). This is good for actions we want to
happen reasonably quickly (like would be normally DBus calls), but not
when we are unsure of program availability schedule (i.e. at startup).
Here not only the handler would run a lot uselessly but it would
likely even slow the startup down by doing so. So while GIMP is not
initialized, switch to half-a-second timeout handler, then only switch
back to idle handler when we are properly initialized and GIMP is
ready to answer calls in a timely manner.
… DBus calls.
In particular, Aryeom would start GIMP and directly double click some
image to be loaded in GIMP in the very short while when splash is
visible. Previous code would wait for the `restored` flag to be TRUE.
This was nearly it as we can actually start loading images as soon as
the 'restore' signal has passed. Yet the flag is set in the main
handler, but we actually also need the <Image> UI manager to exist,
which is created in gui_restore_after_callback() (so also a 'restore'
handler, yet after the main signal handler, i.e. after `restored` is set
to TRUE). Without this, gui_display_create() would fail with a CRITICAL,
hence file_open_with_proc_and_display() as well.
I could have tried to set the `restored` flag later, maybe with some
clever signal handling trick (and handle both the GUI and non-GUI cases,
i.e. I cannot set the flag inside gui_restore_after_callback() as it
would break the non-GUI cases). Instead I go for a simpler logics with a
new `initialized` flag which is only meant to be set once, once
everything has been loaded, i.e. once you can consider GIMP to be fully
running hence ready to process any common runtime command.
This is not a fix, only an extra-ugly workaround so that at the very
least we don't end up with a splash screen taking the whole display on
Wayland.
Basically by setting 1/3 as the max splash size, a Wayland desktop with
no scale ratio will have a splash taking a third of the screen while it
would take 2/3 of the screen with a scale ratio of ×2 (of course, it
will still be very broken with a scale ratio of ×3 but are there
displays needing such high scaling?). The real fix will be when GTK/GDK
fix their API so that it returns what the docs says it should (i.e. a
size in "application pixels" not "device pixels"), as it does on X11,
Windows, macOS… Then we won't create random max size and we will be able
to properly control our splash size.
Note that this neither fixes nor works around the position issue on
Wayland (in my case, the splash was just always on top-left of the
display).
These small glitches have bothered me for a while now, so I finally
fixed these before the dev release!
Basically there were 2 fixes:
1. use the ink extents to compute any drawn area as this is what will be
actually drawn.
2. Not only expose the drawn area of the new text, but also the one of
the previous text in order to be sure all text pixels are correctly
reset (in case the new text is smaller than previous one). I.e. we
must expose the smallest rectangle containing both previous and new
area of text.
When loading a theme on Windows we always get an error like:
themes_theme_change_notify: error parsing [path including drive letter to:]\theme.css: theme.css:8:99Failed to import: Operation not supported
The location points to the end of the filename of the first @ import url string.
This is caused by the string not being an url.
Based on suggestions from Jehan and lillolollo we replace g_file_get_path
with g_file_get_uri since an url is what is expected here.
Since that function already escapes the string we also remove
g_str_escape here.
Orientation is now handled by core code, just next to profile conversion
handling.
One of the first consequence is that we don't need to have a non-GUI
version gimp_image_metadata_load_finish_batch() in libgimp, next to a
GUI version of the gimp_image_metadata_load_finish() function in
libgimpui. This makes for simpler API.
Also a plug-in which wishes to get access to the rotation dialog
provided by GIMP without loading ligimpui/GTK+ (for whatever reason)
will still have the feature.
The main advantage is that the "Don't ask me again" feature is now
handled by a settings in `Preferences > Image Import & Export` as the
"Metadata rotation policy". Until now it was saved as a global parasite,
which made it virtually non-editable once you checked it once (no easy
way to edit parasites except by scripts). So say you refused the
rotation once while checking "Don't ask again", and GIMP will forever
discard the rotation metadata without giving you a sane way to change
your mind. Of course, I could have passed the settings to plug-ins
through the PDB, but I find it a lot better to simply handle such
settings core-side.
The dialog code is basically the same as an app/dialogs/ as it was in
libgimp, with the minor improvement that it now takes the scale ratio
into account (basically the maximum thumbnail size will be bigger on
higher density displays).
Only downside of the move to the core is that this rotation dialog is
raised only when you open an image from the core, not as a PDB call. So
a plug-in which makes say a "file-jpeg-load" PDB call, even in
INTERACTIVE run mode, won't have rotation processed. Note that this was
already the same for embedded color profile conversion. This can be
wanted or not. Anyway some additional libgimp calls might be of interest
to explicitly call the core dialogs.
While this issue was unseen so far on common desktop machines, the CI
build encountered it, hence failing 6 of the unit tests.
A connection to the bus could not be established hence the dbus_manager
was never allocated, and finally it would crash at exit if we tried to
unref it unconditionnally. Use g_clear_object() instead.
Also add some stderr output for easier debugging, for when one of the 2
possible error cases might happen (as documented by g_bus_own_name()).
Tested in a VM. Minimized window is properly deiconified and showed to
the front. Though a window in the back (not minimized) is not moved to
the front.
GimpDisplay contains only the ID logic and the "gimp" and "config"
pointers, and lives in the core.
GimpDisplayImpl is a subclass and contains all the actual display
stuff. The subclass is only an implementation detail and doesn't
appear in any API.
Remove all hacks which pass displays as gpointer, GObject or
GimpObject through the core, or even lookup its type by name,
just use GimpDisplay.
Turn all ID param specs into object param specs (e.g. GimpParamImageID
becomes GimpParamImage) and convert between IDs and objects in
gimpgpparams.c directly above the the wire protocol, so all of app/,
libgimp/ and plug-ins/ can deal directly with objects down to the
lowest level and not care about IDs.
Use the actual object param specs for procedure arguments and return
values again instead of a plain g_param_spec_object() and bring back
the none_ok parameter.
This implies changing the PDB type checking functions to work on pure
integers instead of IDs (one can't check whether object creation is
possible if performing that check requires the object to already
exist).
For example gimp_foo_is_valid() becomes gimp_foo_id_is_valid() and is
not involved in automatic object creation magic at the protocol
level. Added wrappers which still say gimp_foo_is_valid() and take the
respective objects.
Adapted all code, and it all becomes nicer and less convoluted, even
the generated PDB wrappers in app/ and libgimp/.
GimpConfigWriter contains several constructors with the convention
`gimp_config_writer_new_* ()`. This will lead to problems however with
languages like Vala, where it cannot disambiguate the following:
```
// calls config_writer_new_string()
Gimp.ConfigWriter w = new ConfigWriter.string("xxx");
// calls config_writer_string()
w.string("xxx")
```
Using `from_` in constructors is general practice in GObject-bsed
libraries because of this.
This also fixes an error when trying to use vapigen on the GIMP .GIR
file.
which means that it's now included normally via gimpbase.h
and not any longer via gimpbasetypes.h which we only did out
of lazyness. A *lot* of files in libgimp* and app/ now need to
- libgimpbase: change GPParam to transfer all information about the
GValues we use, in the same way done for GPParamDef. GPParam is now
different from GimpParam from libgimp, pointers can't be casted any
longer. The protocol is now completely GimpPDBArgType-free. Remove
gp_params_destroy() from the public API.
- libgimp: add API to convert between an array of GPParams and
GimpValueArray, the latter is now the new official API for dealing
with procedure arguments and return values, GimpParam is cruft (the
wire now talks with GimpPlugIn more directly than with the members
of GimpPlugInInfo, which need additional compat conversions).
- libgimp, app: rename gimpgpparamspecs.[ch] to simply
gimpgpparams.[ch] which is also more accurate because they now
contain GValue functions too. The code that used to live in
app/plug-in/plug-in-params.h is now completely in libgimp.
- app: contains no protocol compat code any longer, the only place
that uses GimpPDBArgType is the PDB query procedure implementation,
which also needs to change.
- app: change some forgotten int32 run-modes to enums.
There are no replacements. Just we must make sure that all GTK+/GDK
calls are run from the main thread, which is already what we were doing.
Actually I don't even think these were doing anything as we were not
calling gdk_threads_init() so the default lock functions were not set
anyway. These were just bogus calls.
Step one: get rid of all those deprecation warnings that make
it hard to see any other warnings:
- add a lot of dummy API to GimpAction, GimpActionGroup, GimpUIManager
etc. which simply forwards to the deprecated GTK functions, they
will all go away again later
- rename GimpAction to GimpActionImpl
- add interface GimpAction that is implemented by all action classes,
creates a common interface and allows to remove some duplicated
logic from GimpToggleAction and GimpRadioAction, and at the same
time adds more features
Include the system-wide gimp.css file, in addition to the user-
specific gimp.css file, in the generated theme.css file, instead of
copying the former into the latter when creating the user's
gimpdir. This allows us to modify the system-wide gimp.css file,
and having the changes take effect in existing installations.
The GUI implementation of gimp_wait() relies on the ability to run
plug-ins (namely, the busy-dialog plug-in) without entering the
main loop. This prohibits the said plug-ins from making any PDB
calls, which would result in a deadlock. However, we're currently
calling gimp_gimprc_query() to fetch the prefer-dark-theme option
during gimp_ui_init() (or any time the theme.css file changes).
Instead, communicate this preference through the theme.css file
itself, by writing a /* prefer-dark-theme */ comment to the file
when the option is set. Yes, it's a bit of a hack :P
When an error occurs, we want to prevent overwriting any previous
version of the file by incomplete contents. So run
g_output_stream_close() with a cancelled GCancellable to do so.
See also discussion in #2565.
I had this funny behavior when I was quitting GIMP with the active tool
using modifiers (for instance bucket fill). Each time I'd quit with
ctrl-q (and if the image is not dirty), the options would use the value
from the modifier state and be saved as-is. Hence at next restart, the
default value was always different!
In the GUI implementation of gimp_wait(), explicitly finish the
input-pipe async operation after the busy-dialog plug-in
terminates, to avoid the async callback function from being
repeatedly called, stalling the main thread. Previously, this code
relied on gimp-parallel implicitly aborting the async operation,
but this is no longer the case since commit
4969d75785.
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
A single icon theme can contain both regular and symbolic icons. Let's
give possibility to switch from one style to the other within GIMP
Preferences.
This won't work very well in all cases yet, especially if an icon theme
only has symbolic icons (and no regular ones) because of inconsistencies
in glib which are being fixed (patches which I submitted and which were
merged in glib on 2018-08-17).
So this will work as expected when we will bump our glib requirement to
whatever is the next release.
Not the most useful type of extensions per-se, but a lot of people seem
to appreciate creating and installing new splashes. Let's make it easy
to install as extensions.
Note that extension splashes are cumulative. So if you enabled several
splash extensions at once, an image would be chosen in random amongst
all of them.
Remove the "independent" parameter of gimp_parallel_run_async(),
and have the function always execute the passed callback in the
shared async thread-pool.
Add a new gimp_parallel_run_async_full() function, taking, in
addition to a callback and a data pointer:
- A priority value, controlling the priority of the callback in
the async thread-pool queue. 0 is the default priority (used
by gimp_parallel_run_async()), negative values have higher
priority, and positive values have lower priority.
- A destructor function for the data pointer. This function is
called to free the user data in case the async operation is
canceled before execution of the callback function begins, and
the operation is dropped from the queue and aborted without
executing the callback. Note that if the callback *is*
executed, the destructor is *not* used -- it's the callback's
responsibility to free/recycle the user data.
Add a separate gimp_parallel_run_async_independent() function,
taking the same parameters, and executing the passed callback in
an independent thread, rather than the thread pool. This function
doesn't take a priority value or a destructor (and there's no
corresponding "_full()" variant that does), since they're pointless
for independent threads.
Adapt the rest of the code to the changes.
Also remove all traces of it from the plug-in protocol and raise the
protocol version to 0x0100 (we now allow features and therefore
version bumps in stable, and the master protocol version should always
be higher). Fix the code that aborts plug-in startup on protocol
version mismatch, we can't use gimp_message() because we have no
protocol.
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.