Hi, here is a program which works in Gtk but fails in Gtkmm. The aim is to be able to mangle the filename of a file chooser used for saving and still get the canonical overwrite confirmation dialog. The problem is a combination of the following: * FileChooser does not yet support file format extensions very well, see for example: http://bugzilla.gnome.org/show_bug.cgi?id=135901 * The confirm-overwrite signal is only emitted *after* Gtk detected a file overwrite. Thus, the confirm-overwrite signal seems useless here. * FileChooserDialog connects early to the response signal of the dialog, because it really, really wants to run its callback first. I don't know a way to squeeze a signal handler before its own handler. See gtkfilechooserdialog.c: /* We do a signal connection here rather than overriding the method in * class_init because GtkDialog::response is a RUN_LAST signal. We want *our* * handler to be run *first*, regardless of whether the user installs response * handlers of his own. */ g_signal_connect (dialog, "response", G_CALLBACK (response_cb), NULL); Additional note: This Gtk::FileChooserDialog behaviour exposes a bug in Bakery 2.4.4: If in the save or save as dialog you enter the filename without the application extension, and the file with extension already exists, that file is silently overwritten. It was my motivation to fix/work around this bug that lead me to this. Work around in C: The attached program fc.c installs a signal handler for the dialog's response signal which, in case the filename needs to be mangled, updates the current name, stops the emission of the response signal, and then emits the response signal again. Although this is kinda hackish, it currently seems to be the only way to achieve this functionality without a medium sized coding effort. This feature was deemed important enough to add a fix when it was broken in Gtk 2.10. See http://bugzilla.gnome.org/show_bug.cgi?id=347883 and the following quote: "I'd say this is definitely a valid use of the API since it's the *only* way of allowing entering filenames without extensions. You can do that in many apps, and the apps simply append the extension in their response() callbacks. The only way of getting the changed filename properly checked is running response() again." -- Michael Natterer How to compile and run the test: $ gcc -o fc fc.c `pkg-config --cflags --libs gtk+-2.0 ` $ touch example.xcf $ ./fc <Enter "example" in the filename field, without extension, and click Save> ** (fc:28341): DEBUG: -3 ** (fc:28341): DEBUG: example.xcf <Confirm by clicking Replace> ** (fc:28341): DEBUG: -3 ** (fc:28341): DEBUG: done: -3 Work around in C++: The attached program fc2.cc is a 1:1 translation of the C test case. I even used a ptr function to handle the signal, but notice that I also tried other variations. $ g++ -o fc2 fc2.cc `pkg-config --cflags --libs gtkmm-2.4 ` $ touch example.xcf $ ./fc <Enter "example" in the filename field, without extension, and click Save> Response: -3 Name: example.xcf done: -3 Note the lack of an overwrite confirmation. I have a more complex test case in the context of a complete application where a similar approach leads to a segfault in gtkfilechooserdialog.c:confirm_dialog_should_accept_filename() because toplevel is NULL. In that case it seems as if the GtkFileChooserDefault widget is de-parented (removed from the dialog) before the response signal is emitted again. I can not reproduce this in the simple fc2.cc, and I am not sure that information helps. In any case, there is something wrong here. I would appreciate it if you could advise me on how to proceed. Thanks, Marcus
Attachment:
fc.c
Description: Binary data
Attachment:
fc2.cc
Description: Binary data