Search code examples
macosgtk3

GTK3: The contents of dialog wndows on MacOS cannot be accessed on initial display


I am using the GTK3 library for a cross platform application.

On MacOS, When a dialog is displayed, the dialog window appears to be active and focused. The main window's close button is grey, the dialog window's close button is red. The dialog window's close button works.

But clicking within the dialog window switches the focus back to the main window. The user cannot interact with the contents of the dialog window. The user must click on the dialog window again to be able to interact with the contents.

gtk_window_present() does not help. I figured out how to get the NSWindow handle for the window, and tried using makeKeyAndOrderFront: on the dialog window, but that did not help.

Considering that the close button works on the dialog, the window does have focus, but I don't know why the contents are not interacting with the mouse.

Does anyone have any ideas on what to try to allow the mouse to interact with the contents of the dialog window?

GTK or Mac OS API (Objective-C) solutions are both welcome.

The dialogs work properly on Linux and Windows.

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include <gtk/gtk.h>

enum {
  STATE_OFF,
  STATE_PREP,
  STATE_PROCESS,
};

enum {
  RESPONSE_NONE,
  RESPONSE_CLOSE,
  RESPONSE_APPLY,
};

bool  done = false;
int   state = STATE_OFF;
int   response = RESPONSE_NONE;

static gboolean winclosecb (GtkWidget *window, GdkEvent *event, gpointer udata);
static void     buttonclickcb (GtkButton *b, gpointer udata);
static void     dialogrespcb (GtkDialog *d, gint responseid, gpointer udata);

int
main (int argc, char *argv [])
{
  argc = 0;
  GtkWidget   *window;
  GtkWidget   *vbox;
  GtkWidget   *hbox;
  GtkWidget   *widget;
  GtkWidget   *dialog = NULL;


  gtk_init (&argc, NULL);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
  gtk_window_set_title (GTK_WINDOW (window), "test-mac-dialog");
  gtk_window_set_default_size (GTK_WINDOW (window), 500, 300);
  g_signal_connect (window, "delete-event", G_CALLBACK (winclosecb), NULL);

  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  widget = gtk_button_new ();
  gtk_button_set_label (GTK_BUTTON (widget), "button");
  g_signal_connect (widget, "clicked", G_CALLBACK (buttonclickcb), NULL);
  gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);

  gtk_widget_show_all (window);
  gtk_window_present (GTK_WINDOW (window));

  while (! done) {
    gtk_main_iteration_do (FALSE);
    while (gtk_events_pending ()) {
      gtk_main_iteration_do (FALSE);
    }

    if (state == STATE_PROCESS) {
      if (response != RESPONSE_NONE) {
        response = RESPONSE_NONE;
        gtk_widget_hide (GTK_WIDGET (dialog));
        state = STATE_OFF;
      }
    }

    if (state == STATE_PREP) {
      if (dialog == NULL) {
        dialog = gtk_dialog_new ();
        gtk_window_set_title (GTK_WINDOW (dialog), "dialog");
        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
        gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
        gtk_dialog_add_button (GTK_DIALOG (dialog), "Close", RESPONSE_CLOSE);
        gtk_dialog_add_button (GTK_DIALOG (dialog), "Go", RESPONSE_APPLY);
        g_signal_connect (dialog, "response", G_CALLBACK (dialogrespcb), NULL);
      }
      gtk_widget_show_all (GTK_WIDGET (dialog));
      state = STATE_PROCESS;
    }
  }

  gtk_widget_destroy (window);
  gtk_main_iteration_do (FALSE);
  while (gtk_events_pending ()) {
    gtk_main_iteration_do (FALSE);
  }
  return 0;
}

static gboolean
winclosecb (GtkWidget *window, GdkEvent *event, gpointer udata)
{
  done = true;
  return true;
}

static void
buttonclickcb (GtkButton *b, gpointer udata)
{
  state = STATE_PREP;
}

static void
dialogrespcb (GtkDialog *d, gint responseid, gpointer udata)
{
  if (responseid == RESPONSE_CLOSE) {
    fprintf (stderr, "dialog close\n");
  }
  if (responseid == RESPONSE_APPLY) {
    fprintf (stderr, "dialog apply\n");
  }
  response = responseid;
}

Compilation Script:

#!/bin/bash

cc $(pkg-config --cflags gtk+-3.0) -o tt tt.c $(pkg-config --libs gtk+-3.0)

I am using the GTK from MacPorts, currently at version 3.24.34. This is on Mac OS Ventura, I have not tried other versions of Mac OS as yet.


Solution

  • Upgrading MacPorts GTK3 to version 3.24.37 fixes the issue.

    The Portfile changes may not work with other MacPorts packages. The original 3.24.36 portfile changes were created by ctreleaven (Craig Treleaven). The only changes below are the updates to 3.24.37.

    Portfile diff:

    diff --git a/gnome/gtk3-devel/Portfile b/gnome/gtk3-devel/Portfile
    index d5fe438f929..0a0d781b7b7 100644
    --- a/gnome/gtk3-devel/Portfile
    +++ b/gnome/gtk3-devel/Portfile
    @@ -6,12 +6,13 @@ PortGroup           xcodeversion 1.0
     PortGroup           active_variants 1.1
     PortGroup           compiler_blacklist_versions 1.0
     PortGroup           legacysupport 1.1
    +PortGroup           meson 1.0
     
     name                gtk3-devel
     conflicts           gtk3
     set my_name         gtk3
    -version             3.24.34
    -revision            2
    +version             3.24.37
    +revision            0
     epoch               0
     
     set proj_name       gtk+
    @@ -33,10 +34,9 @@ distname            ${proj_name}-${version}
     dist_subdir         ${my_name}
     use_xz              yes
     master_sites        gnome:sources/${proj_name}/${branch}/
    -
    -checksums           rmd160  2060a89575f9adf938bf91e4f06935ea619f7577 \
    -                    sha256  dbc69f90ddc821b8d1441f00374dc1da4323a2eafa9078e61edbe5eeefa852ec \
    -                    size    21587592
    +checksums           rmd160  afab13f415e5923bb185d923f3a37734e0f346d7 \
    +                    sha256  6745f0b4c053794151fd0f0e2474b077cccff5f83e9dd1bf3d39fe9fe5fb7f57 \
    +                    size    12401196
     
     minimum_xcodeversions {9 3.1}
     
    @@ -59,9 +59,7 @@ depends_run         port:shared-mime-info \
     # darwin 10 and earlier requires legacy support for O_CLOEXEC
     legacysupport.newest_darwin_requires_legacy 10
     
    -# use autoreconf to deal with dependency tracking issues in configure
    -use_autoreconf      yes
    -autoreconf.args     -fvi
    +patchfiles         patch-meson_build.diff
     
     # gtk3 +quartz uses instancetype which is not available
     # before approximately Xcode 4.6 (#49391)
    @@ -84,10 +82,10 @@ if {${universal_possible} && [variant_isset universal]} {
             lappend merger_destroot_args(${arch})  CC_FOR_BUILD='${configure.cc} -arch ${arch}'
         }
     } else {
    -    build.args-append       CC="${configure.cc} ${configure.cc_archflags}" \
    -                            CC_FOR_BUILD="${configure.cc} ${configure.cc_archflags}"
    -    destroot.args-append    CC="${configure.cc} ${configure.cc_archflags}" \
    -                            CC_FOR_BUILD="${configure.cc} ${configure.cc_archflags}"
    +#     build.args-append       CC="${configure.cc} ${configure.cc_archflags}" \
    +#                             CC_FOR_BUILD="${configure.cc} ${configure.cc_archflags}"
    +#     destroot.args-append    CC="${configure.cc} ${configure.cc_archflags}" \
    +#                             CC_FOR_BUILD="${configure.cc} ${configure.cc_archflags}"
     }
     
     pre-configure {
    @@ -104,23 +102,23 @@ configure.cppflags-append \
     configure.cflags-append \
                         -fstrict-aliasing
     
    -configure.args      --enable-static \
    -                    --disable-glibtest \
    -                    --enable-introspection \
    -                    --disable-wayland-backend \
    -                    --disable-schemas-compile \
    -                    gio_can_sniff=yes
    -
    -build.args-append   V=1 \
    -                    CPP_FOR_BUILD="${configure.cpp}"
    +configure.args      -Dgtk_doc=false \
    +                    -Dman=true \
    +                    -Dintrospection=true \
    +                    -Ddemos=false \
    +                    -Dexamples=false \
    +                    -Dtests=false \
    +                    -Dprofiler=false
     
    +# almost all tests failing??
     test.run            yes
    -test.target         check
    +
    +destroot.post_args-append -v
     
     post-destroot {
         set docdir ${prefix}/share/doc/${name}
         xinstall -d ${destroot}${docdir}
    -    xinstall -m 644 -W ${worksrcpath} AUTHORS COPYING HACKING NEWS README \
    +    xinstall -m 644 -W ${worksrcpath} CONTRIBUTING.md COPYING NEWS README.md \
             ${destroot}${docdir}
     
         # avoid conflict with the gtk-update-icon-cache installed by gtk2
    @@ -146,7 +144,7 @@ platform darwin {
             }
     
             # https://trac.macports.org/ticket/63151
    -        configure.args-append --disable-dependency-tracking
    +#         configure.args-append --disable-dependency-tracking
         }
     
         if {${os.major} <= 10} {
    @@ -157,7 +155,7 @@ platform darwin {
         }
         if {${os.major} <= 12} {
             # requires cups 1.7
    -        configure.args-append --disable-cups
    +        configure.args-append -Dprint_backends=file,lpr,test
         }
     }
     
    @@ -240,7 +238,8 @@ variant quartz conflicts x11 {
         require_active_variants path:lib/pkgconfig/cairo.pc:cairo quartz
         require_active_variants path:lib/pkgconfig/pango.pc:pango quartz
     
    -    configure.args-append   --enable-quartz-backend
    +    configure.args-append  -Dx11_backend=false \
    +                           -Dquartz_backend=true
     }
     
     variant x11 conflicts quartz {
    @@ -256,10 +255,9 @@ variant x11 conflicts quartz {
                                 port:xorg-libXfixes \
                                 port:at-spi2-atk
     
    -    configure.args-append   --enable-xinerama \
    -                            --x-include=${prefix}/include \
    -                            --x-lib=${prefix}/lib \
    -                            --enable-x11-backend
    +    configure.args-append  -Dx11_backend=true \
    +                           -Dquartz_backend=false \
    +                           -Dxinerama=yes
     }
     
     if {![variant_isset quartz]} {