@@ -824,13 +824,22 @@ public boolean getVisible () {
824824
825825@ Override
826826long 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 ();
827+ if (GTK .GTK4 ) {
828+ if ((style & SWT .BAR ) != 0 ) {
829+ /*
830+ * The GtkPopoverMenuBar has been mapped, which means its internal
831+ * GtkPopoverMenuBarItem children now exist. Find the GtkPopoverMenu child for each,
832+ * and connect SHOW/HIDE signals so that SWT MenuListeners on DROP_DOWN are notified.
833+ */
834+ connectDropDownMenuSignals ();
835+ } else if ((style & SWT .POP_UP ) != 0 ) {
836+ /*
837+ * The POP_UP GtkPopoverMenu has been mapped. Its handle IS the GtkPopoverMenu,
838+ * and nested GtkPopoverMenu children for any CASCADE submenus already exist in
839+ * its widget tree. Connect SHOW/HIDE signals for those nested submenus now.
840+ */
841+ connectCascadeSubMenuSignals (this , handle );
842+ }
834843 }
835844 return super .gtk_map (widget );
836845}
@@ -845,16 +854,67 @@ private void connectDropDownMenuSignals() {
845854 if (menuItem .menu != null && menuItem .menu .popoverHandle == 0 ) {
846855 long popover = findGtkPopoverMenuChild (barItem );
847856 if (popover != 0 ) {
857+ OS .g_object_ref (popover );
848858 menuItem .menu .popoverHandle = popover ;
849859 display .addWidget (popover , menuItem .menu );
850860 OS .g_signal_connect_closure_by_id (popover , display .signalIds [SHOW ], 0 , display .getClosure (SHOW ), false );
851861 OS .g_signal_connect_closure_by_id (popover , display .signalIds [HIDE ], 0 , display .getClosure (HIDE ), false );
862+ /*
863+ * Also connect SHOW/HIDE signals for nested CASCADE submenus.
864+ */
865+ connectCascadeSubMenuSignals (menuItem .menu );
852866 }
853867 }
854868 barItem = GTK4 .gtk_widget_get_next_sibling (barItem );
855869 }
856870}
857871
872+ private void connectCascadeSubMenuSignals (Menu menu ) {
873+ connectCascadeSubMenuSignals (menu , menu .popoverHandle );
874+ }
875+
876+ private void connectCascadeSubMenuSignals (Menu menu , long parentPopoverHandle ) {
877+ if (menu == null || parentPopoverHandle == 0 || menu .items == null ) return ;
878+ for (MenuItem item : menu .items ) {
879+ if ((item .style & SWT .CASCADE ) != 0 && item .menu != null ) {
880+ /*
881+ * item.menu is the CASCADE submenu (always SWT.DROP_DOWN style).
882+ * Its popoverHandle is 0 until we find and register its GtkPopoverMenu.
883+ * Skip if already connected (popoverHandle != 0).
884+ */
885+ if (item .menu .popoverHandle != 0 ) continue ;
886+ long nestedPopover = findNestedPopoverForModel (parentPopoverHandle , item .menu .modelHandle );
887+ if (nestedPopover != 0 ) {
888+ OS .g_object_ref (nestedPopover );
889+ item .menu .popoverHandle = nestedPopover ;
890+ display .addWidget (nestedPopover , item .menu );
891+ OS .g_signal_connect_closure_by_id (nestedPopover , display .signalIds [SHOW ], 0 , display .getClosure (SHOW ), false );
892+ OS .g_signal_connect_closure_by_id (nestedPopover , display .signalIds [HIDE ], 0 , display .getClosure (HIDE ), false );
893+ // Recurse to handle further nested CASCADE submenus
894+ connectCascadeSubMenuSignals (item .menu );
895+ }
896+ }
897+ }
898+ }
899+
900+ private long findNestedPopoverForModel (long parentWidget , long targetModel ) {
901+ if (parentWidget == 0 || targetModel == 0 ) return 0 ;
902+ long child = GTK4 .gtk_widget_get_first_child (parentWidget );
903+ while (child != 0 ) {
904+ if (GTK4 .GTK_IS_POPOVER_MENU (child )) {
905+ long model = GTK4 .gtk_popover_menu_get_menu_model (child );
906+ if (model == targetModel ) {
907+ return child ;
908+ }
909+ }
910+ long found = findNestedPopoverForModel (child , targetModel );
911+ if (found != 0 ) return found ;
912+ child = GTK4 .gtk_widget_get_next_sibling (child );
913+ }
914+ return 0 ;
915+ }
916+
917+
858918private long findGtkPopoverMenuChild (long barItem ) {
859919 long child = GTK4 .gtk_widget_get_first_child (barItem );
860920 while (child != 0 ) {
@@ -955,7 +1015,7 @@ void hookEvents() {
9551015 if ((style & SWT .DROP_DOWN ) == 0 ) {
9561016 OS .g_signal_connect_closure_by_id (handle , display .signalIds [SHOW ], 0 , display .getClosure (SHOW ), false );
9571017 OS .g_signal_connect_closure_by_id (handle , display .signalIds [HIDE ], 0 , display .getClosure (HIDE ), false );
958- if ((style & SWT .BAR ) != 0 ) {
1018+ if ((style & ( SWT .BAR | SWT . POP_UP ) ) != 0 ) {
9591019 /*
9601020 * Connect MAP signal on the GtkPopoverMenuBar so that once it is
9611021 * realized and its internal GtkPopoverMenuBarItem children exist,
@@ -1102,6 +1162,7 @@ void deregister() {
11021162 super .deregister ();
11031163 if (GTK .GTK4 && (style & SWT .DROP_DOWN ) != 0 && popoverHandle != 0 ) {
11041164 display .removeWidget (popoverHandle );
1165+ OS .g_object_unref (popoverHandle );
11051166 popoverHandle = 0 ;
11061167 }
11071168}
0 commit comments