@@ -37,6 +37,19 @@ struct ARGS
37
37
int i ;
38
38
};
39
39
40
+ typedef struct POPUP_ARGS POPUP_ARGS ;
41
+
42
+ struct POPUP_ARGS
43
+ {
44
+ /* Must be first. */
45
+ ARGS_BASE base ;
46
+
47
+ GtkWidget * gtk_window ;
48
+ ALLEGRO_MENU * menu ;
49
+ int x ;
50
+ int y ;
51
+ };
52
+
40
53
41
54
static void build_menu (GtkWidget * gmenu , ALLEGRO_MENU * amenu );
42
55
@@ -368,14 +381,12 @@ static void popop_on_hide(ALLEGRO_MENU *menu)
368
381
/* [gtk thread] */
369
382
static gboolean do_show_popup_menu (gpointer data )
370
383
{
371
- ARGS * args = (ARGS * ) data ;
384
+ POPUP_ARGS * args = (POPUP_ARGS * ) data ;
372
385
373
386
_al_gtk_lock_args (args );
374
387
375
- GtkWidget * menu = NULL ;
376
388
if (!args -> menu -> extra1 ) {
377
- menu = gtk_menu_new ();
378
-
389
+ GtkWidget * menu = gtk_menu_new ();
379
390
build_menu (menu , args -> menu );
380
391
381
392
gtk_widget_show (menu );
@@ -385,22 +396,33 @@ static gboolean do_show_popup_menu(gpointer data)
385
396
G_CALLBACK (popop_on_hide ), (gpointer ) args -> menu );
386
397
}
387
398
388
- bool position_called = false;
389
- if (menu )
390
- /* gtk_menu_popup_at_widget only exists in gtk newer than 3.22 */
391
399
#if GTK_CHECK_VERSION (3 , 22 , 0 )
392
- gtk_menu_popup_at_widget (args -> menu -> extra1 , menu , GDK_GRAVITY_SOUTH_WEST ,
393
- GDK_GRAVITY_NORTH_WEST ,
394
- NULL );
400
+ GtkWidget * vbox = gtk_bin_get_child (GTK_BIN (args -> gtk_window ));
401
+ GList * list = gtk_container_get_children (GTK_CONTAINER (vbox ));
402
+ int menu_height = 0 ;
403
+ if (g_list_length (list ) == 2 ) {
404
+ GtkAllocation alloc ;
405
+ gtk_widget_get_allocation (GTK_WIDGET (list -> data ), & alloc );
406
+ menu_height = alloc .height ;
407
+ }
408
+ g_list_free (list );
409
+
410
+
411
+ GdkSeat * seat = gdk_display_get_default_seat (
412
+ gdk_window_get_display (gtk_widget_get_window (args -> gtk_window )));
413
+ GdkDevice * device = gdk_seat_get_pointer (seat );
414
+ GdkEventButton event = { };
415
+ event .type = GDK_BUTTON_RELEASE ;
416
+ event .time = GDK_CURRENT_TIME ;
417
+ event .device = device ;
418
+ GdkRectangle rect = { .x = args -> x , .y = args -> y + menu_height , .width = 1 , .height = 1 };
419
+ gtk_menu_popup_at_rect (args -> menu -> extra1 , gtk_widget_get_window (args -> gtk_window ),
420
+ & rect , GDK_GRAVITY_SOUTH_WEST , GDK_GRAVITY_NORTH_WEST , (GdkEvent * )& event );
395
421
#else
396
- gtk_menu_popup (args -> menu -> extra1 , NULL , NULL , NULL , NULL , 1 , 0 );
422
+ gtk_menu_popup (args -> menu -> extra1 , NULL , NULL , NULL , NULL , 1 , 0 );
397
423
#endif
398
424
399
- if (!position_called ) {
400
- ALLEGRO_DEBUG ("Position canary not called, most likely the menu didn't show "
401
- "up due to outstanding mouse events.\n" );
402
- }
403
- args -> base .response = position_called ;
425
+ args -> base .response = true;
404
426
405
427
_al_gtk_release_args (args );
406
428
@@ -409,15 +431,23 @@ static gboolean do_show_popup_menu(gpointer data)
409
431
410
432
bool _al_show_popup_menu (ALLEGRO_DISPLAY * display , ALLEGRO_MENU * menu )
411
433
{
412
- ARGS args ;
413
- (void )display ;
434
+ GtkWidget * gtk_window ;
435
+ POPUP_ARGS args ;
436
+ ALLEGRO_MOUSE_STATE state ;
437
+
438
+ al_get_mouse_state (& state );
439
+
440
+ if (!(gtk_window = _al_gtk_get_window (display )))
441
+ return false;
414
442
415
443
if (!_al_gtk_init_args (& args , sizeof (args ))) {
416
444
return false;
417
445
}
418
446
419
- args .gtk_window = NULL ;
447
+ args .gtk_window = gtk_window ;
420
448
args .menu = menu ;
449
+ args .x = al_get_mouse_state_axis (& state , 0 );
450
+ args .y = al_get_mouse_state_axis (& state , 1 );
421
451
422
452
return _al_gtk_wait_for_args (do_show_popup_menu , & args );
423
453
}
0 commit comments