0

I have a custom GtkFileChooserDialog created with Glade. The Modal property is marked. I also have a GtkFileChooserButton that uses this GtkFileChooserDialog as its dialog:

class ImgChooserBttWithCapture(Gtk.FileChooserButton):
    """
    The custom Gtk.FileChooserButton and Gtt.FileChooserDialog with a button for call capture app
    """

    def __init__(self, cap_app_path):
        self.builder = Gtk.Builder.new_from_file(
            UIS_PATH + 'images_chooser_dialog.xml')
        self.chooser_dialog = self.builder.get_object('icd_photo_chsrdialog')

        super().__init__(dialog=self.chooser_dialog)
        self.cap_app_path = cap_app_path
        self.set_title('Selecione uma imagem')
        self.set_halign(Gtk.Align.START)
        self.set_valign(Gtk.Align.FILL)
        self.set_hexpand(True)
        self.set_tooltip_text('Clique para escolher uma nova imagem')
        self.set_local_only(False)

        handlers = {'onCaptureButtonClicked': self._on_capture_button_clicked}

        self.builder.connect_signals(handlers)

    def _on_capture_button_clicked(self, button):

        try:
            subprocess.call([self.cap_app_path])
        except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError) as ex:

            self.builder.add_from_file(UIS_PATH + 'information_window.xml')
            msg_dialog = self.builder.get_object('iw_messagedialog')

            msg_dialog.set_title('Erro')
            msg_dialog.set_markup(
                '<span size="12000"><b>Não foi possível abrir o aplicativo</b></span>')

            msg_dialog.format_secondary_markup(
                'O aplicativo de captura não está disponível.\nVerifique o caminho para o aplicativo de caputura em configurações.\n' + '<span foreground="red"><u>' + str(ex) + '</u></span>')

            msg_dialog.set_property('message-type', Gtk.MessageType.ERROR)
            msg_dialog.set_transient_for(self.chooser_dialog)
            self.builder.get_object('iw_message_image').set_from_file(
                'views/uis/images/message_error.png')

            msg_dialog.run()
            msg_dialog.destroy()

But, when I click on the button, the dialog is not modal, that is, I can interact with the other window.

Matheus Saraiva
  • 1,144
  • 1
  • 11
  • 33
  • 2
    It's possible that "modal" isn't really respected unless you set "transient-for" property as well. – Jussi Kukkonen Oct 06 '16 at 10:40
  • I added `self.chooser_dialog.set_transient_for(parent)` below the `self.chooser_dialog = self.builder.get_object('icd_photo_chsrdialog')`. `parent` is passed through the constructor `def __init__(self, cap_app_path, parent):`. But the problem remains. `parent` is a GtkApplicationWindow – Matheus Saraiva Oct 06 '16 at 15:01
  • Although I can interact with the other window (the parent window), the `GtkFileChooserDialog` continues in front of the parent window. But I can interact with buttons, menus and others components of parent window even though she is in the background. I think this is a bug of 3.20 version because I was running the same code in version 3.18 and it worked perfectly. How could I get around this? – Matheus Saraiva Oct 06 '16 at 15:50
  • Which dialog isn't modal, the file chooser dialog or the message dialog? – andlabs Oct 07 '16 at 03:15
  • The file chooser dialog. The message dialog is modal. But the file chooser dialog is not modal. – Matheus Saraiva Oct 07 '16 at 11:40
  • A possible solution for get around this problem is `set_sensitive(False)` on the `parent` window when the `GtkFileChooserButton` is clicked and `set_sensitive(True)` when the `GtkFileChooserDialog` is closed. But I still have not tested. – Matheus Saraiva Oct 07 '16 at 14:40

1 Answers1

0

Would grabbing the pointer work for you?

//pass all events to window apart LEAVE_NOTIFY_MASK 
MainWindow->set_events(GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK);
MainWindow->set_modal(true);
auto display = MainWindow->get_display();
auto window = MainWindow->get_window();
auto grabSuccess = display->get_default_seat()->grab(window, Gdk::SEAT_CAPABILITY_ALL, true);
if(grabSuccess != Gdk::GRAB_SUCCESS)
{
    std::clog<<"grab failed: "<<grabSuccess<<std::endl;
}
Community
  • 1
  • 1
pan-mroku
  • 803
  • 6
  • 17
  • Not the MainWindow to be modal, but the `GtkFileChooserDialog` she calls. Palliative I set the `parent` (MainWindow) to `set_sensitive(False)` when the `GtkFileChooserButton` is clicked and `set_sensitive(True)` when the `GtkFileChooserDialog` is hided. But I had to use the event `button-release-event` of `GtkFileChooserButton` because with `button-press-event` not work. – Matheus Saraiva Oct 07 '16 at 17:57
  • `MainWindow` in my code is your `self.chooser_dialog`. Dialogs are a subclass of Windows. Window must be realized to grab a pointer. – pan-mroku Oct 10 '16 at 15:31
  • This isn't what grabs are intended for, and trying to do it this way will break if any of the controls in the child dialog grab (comboboxes, for instance). – andlabs Oct 11 '16 at 04:18