@@ -55,7 +55,7 @@ public class Menu extends Widget {
5555 long menuHandle ;
5656
5757 /** GTK4 only fields */
58- long modelHandle , actionGroup , shortcutController ;
58+ long modelHandle , popoverHandle , actionGroup , shortcutController ;
5959
6060 class Section {
6161 LinkedList <MenuItem > sectionItems ;
@@ -822,6 +822,50 @@ public boolean getVisible () {
822822 return GTK .gtk_widget_get_mapped (handle );
823823}
824824
825+ @ Override
826+ long gtk_map (long widget ) {
827+ if (GTK .GTK4 && (style & SWT .BAR ) != 0 ) {
828+ /*
829+ * The GtkPopoverMenuBar has been mapped, which means its internal
830+ * GtkPopoverMenuBarItem children now exist. Find the GtkPopoverMenu child for each,
831+ * and connect SHOW/HIDE signals so that SWT MenuListeners on DROP_DOWN are notified.
832+ */
833+ connectDropDownMenuSignals ();
834+ }
835+ return super .gtk_map (widget );
836+ }
837+
838+ private void connectDropDownMenuSignals () {
839+ if (items == null ) return ;
840+ long barItem = GTK4 .gtk_widget_get_first_child (handle );
841+
842+ for (MenuItem menuItem : items ) {
843+ if (barItem == 0 ) break ;
844+ if ((menuItem .style & SWT .SEPARATOR ) != 0 ) continue ;
845+ if (menuItem .menu != null && menuItem .menu .popoverHandle == 0 ) {
846+ long popover = findGtkPopoverMenuChild (barItem );
847+ if (popover != 0 ) {
848+ menuItem .menu .popoverHandle = popover ;
849+ display .addWidget (popover , menuItem .menu );
850+ OS .g_signal_connect_closure_by_id (popover , display .signalIds [SHOW ], 0 , display .getClosure (SHOW ), false );
851+ OS .g_signal_connect_closure_by_id (popover , display .signalIds [HIDE ], 0 , display .getClosure (HIDE ), false );
852+ }
853+ }
854+ barItem = GTK4 .gtk_widget_get_next_sibling (barItem );
855+ }
856+ }
857+
858+ private long findGtkPopoverMenuChild (long barItem ) {
859+ long child = GTK4 .gtk_widget_get_first_child (barItem );
860+ while (child != 0 ) {
861+ if (GTK4 .GTK_IS_POPOVER_MENU (child )) {
862+ return child ;
863+ }
864+ child = GTK4 .gtk_widget_get_next_sibling (child );
865+ }
866+ return 0 ;
867+ }
868+
825869@ Override
826870long gtk_hide (long widget ) {
827871 if ((style & SWT .POP_UP ) != 0 ) {
@@ -911,6 +955,15 @@ void hookEvents() {
911955 if ((style & SWT .DROP_DOWN ) == 0 ) {
912956 OS .g_signal_connect_closure_by_id (handle , display .signalIds [SHOW ], 0 , display .getClosure (SHOW ), false );
913957 OS .g_signal_connect_closure_by_id (handle , display .signalIds [HIDE ], 0 , display .getClosure (HIDE ), false );
958+ if ((style & SWT .BAR ) != 0 ) {
959+ /*
960+ * Connect MAP signal on the GtkPopoverMenuBar so that once it is
961+ * realized and its internal GtkPopoverMenuBarItem children exist,
962+ * we can find the GtkPopoverMenu for each DROP_DOWN submenu and
963+ * route SHOW/HIDE signals back to the SWT DROP_DOWN Menu.
964+ */
965+ OS .g_signal_connect_closure_by_id (handle , display .signalIds [MAP ], 0 , display .getClosure (MAP ), false );
966+ }
914967 }
915968
916969 } else {
@@ -1044,6 +1097,15 @@ void destroyWidget () {
10441097 }
10451098}
10461099
1100+ @ Override
1101+ void deregister () {
1102+ super .deregister ();
1103+ if (GTK .GTK4 && (style & SWT .DROP_DOWN ) != 0 && popoverHandle != 0 ) {
1104+ display .removeWidget (popoverHandle );
1105+ popoverHandle = 0 ;
1106+ }
1107+ }
1108+
10471109/**
10481110 * Removes the listener from the collection of listeners who will
10491111 * be notified when the menu events are generated for the control.
0 commit comments