-
Notifications
You must be signed in to change notification settings - Fork 772
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
Make some dialogs compatible with GTK4 #4763
Conversation
I must look into it deeper tomorrow. But a general question, why do we still need inheritance here. I would love to get rid of the GladeGui class, and the dialog class should also be overkill. Instead I would prefer a general dialog generator, which only depends on the handler and optionally the glade file. Also, how do you want to handle functions, which return a value from the dialog, after blocking on it? We must basically rewrite all those functions to some sort of state machine, keeping track of the dialogs state. With c++20 we could use coroutines instead. They wouldn't touch our control flow. |
Yes, GladeGui seems redundant. The Dialog base class is used for its destructor:
The actual window only gets destroyed if the Dialog gets destroyed, so any dev could spot if there were a data leak (there'd still be a window...).
The callback should rely on two different set of variables:
Dummy example
So here, Type 1. is no issue, we already have the getters for those, and
I am not sure this changes the structure of Dialog and descendents. The point with using coroutines here is, I guess, that we can give a coroutine's resume() as a callback function for our dialogs. |
Regarding windows, I can tell that it works, we are using clang-cl as compiler and |
Ok, but those handlers could also know, that it has to handle the superclass, therefore the base lass could be completely protected.
Value is not initialized yet. The dlg may not even spawned at that point. And how do we want to handle the case, where caller wants to return a value determined by the Dialog?
Without coroutines, those values must be moved into the dialogs own state or must live in the surrounding newly written state Maschine. Which itself should be managed via the lifetime of the dialog(to prevent a global state for the state machine@ ).
The code will look like this for a caller with an value return:
xoj::task must implement the coroutine interface of cause. |
I wasn't clear here: this is an example as in master: dlg.show() is blocking (so value is initialized). We want to adapt this. |
Ah ok, this example is not problematic I think. Because we are here in the C domain and those gtk calls only support pointers, not small types, you must create either a data/handler class, which you pass as pointer, allocated on the heap, or you allocate the callback (a lambda with captures) directly in dynamic storage. The more problematic cases are all those, where the result is used after the return of the control flow.
Or simple calls, which return the result of the Dialog
|
1c8f995
to
319fa88
Compare
I think I got to a structure that feels right and fits all cases I've encountered so far. |
Yes, your code looked also relatively good so far. Cases like the ones |
a0cccad
to
e9e1064
Compare
I rebased on master, integrated @Febbe's comment, removed the debug outputs and updated the PR description. I think this is ready for a full review (and some testing). I'll keep working on new dialogs in a follow-up PR (to keep things reviewable). |
b24cf59
to
eb3ba9a
Compare
@rolandlo do you have time to test this in production? I don't have much time because I'm writing my thesis right now. But I can still do code reviews. |
Yes, I can test it thoroughly. |
dd520cf
to
db8239a
Compare
Hello! Showing dialogs without nested loops is definitely the best way forward. Anyway, as a porting aid, gtk_dialog_run() can be reintroduced as in https://gitlab.com/inkscape/inkscape/-/merge_requests/5373 https://gitlab.com/inkscape/inkscape/-/blob/827e13285f/src/ui/dialog-run.cpp#L10 |
I rebased onto the latest master and tested a little bit.
|
7341f67
to
1ccb772
Compare
Alright, I think this is stable enough and up for review. |
There are some rounding errors for the opacity value in the fill opacity dialog. When I close and reopen the dialog, I would expect to get the same value displayed again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than the (superfluous and non-working) minimize and maximize buttons I didn't find a regression from this PR. The missing accuracy in the fill opacity dialog was already present before (although slightly differently it seems).
On a positive note: My stylus interacts with the dialogs (in particular with the buttons) just fine, which was mostly not the case with the old dialogs.
I have also noticed that the new dialogs can be moved and the main window can be resized while the dialogs are open. That looks advantageous to me, but I don't know if it was intended.
This comes from the fact that the dialog displays a value /100, while the stored data is /255. There is a rounding error there. We could replace the displayed 100 by 255 if you think this'd look cleaner. |
Did some more tests:
|
The relevant settings in the Gnome tweaks tool can also be obtained via
|
* GtkBuilder wrapper * GtkWindow unique_ptr * PopupWindowwWrapper handling safe post-callback data deletion
1ccb772
to
b3bf013
Compare
Rebased onto master. Merging in 48 hours unless an objection is raised. |
Ok, I'm fine with that. |
This is an attempt to adapt our handling of dialogs, and make it compatible with Gtk4 (different from @Febbe's in the gtk4 branch).
As mentionned in #2722, the main problem is that dialogs in Gtk4 are not blocking. The philosophy is: noone should ever block the main loop, if you're waiting for something, make your response a callback.
I propose here a wrapper around
Dialog
s: it behaves like a smart pointer, but transfers theDialog
's destruction to the associated window's closing signal once the dialog is shown.I also change GtkDialog's into GtkWindow's, as GtkDialog's are deprecated in Gtk4.
For now, I implemented the changes to AboutDialog, FillOpacityDialog, ExportDialog, GotoDialog and FormatDialog.
Except for the first one, the commits are independent and can be reviewed one by one.
Those dialogs should compile fine with GTK4, but some properties set in the UI files will need to be replaced when the switch actually happens (e.g. a widget-based
<property name="has-default">true</property>
will need to be replaced by a window-wide<property name="default-widget">widgetID</property>
).I'll work on more dialogs in a follow up PR.
Edit: updated PR description