@@ -718,8 +718,7 @@ bool Menu::Open(const PositioningStrategy& strategy, Placement placement) {
718718 GdkRectangle frame_rectangle;
719719 gdk_window_get_frame_extents (gdk_window, &frame_rectangle);
720720
721- // Get title bar height from GtkWindow
722- int title_bar_height = 0 ;
721+ // Get GtkWindow for window position and title bar
723722 GtkWindow* gtk_window = nullptr ;
724723 GList* toplevels = gtk_window_list_toplevels ();
725724 for (GList* l = toplevels; l != nullptr ; l = l->next ) {
@@ -732,15 +731,39 @@ bool Menu::Open(const PositioningStrategy& strategy, Placement placement) {
732731 }
733732 g_list_free (toplevels);
734733
734+ // Get window position using gtk_window_get_position (works better on Wayland)
735+ gint window_x = 0 , window_y = 0 ;
736+ if (gtk_window) {
737+ gtk_window_get_position (gtk_window, &window_x, &window_y);
738+ } else {
739+ // Fallback to gdk_window_get_origin if gtk_window not found
740+ gdk_window_get_origin (gdk_window, &window_x, &window_y);
741+ }
742+
743+ // Get title bar height from GtkWindow
744+ int title_bar_height = 0 ;
735745 if (gtk_window) {
736746 GtkWidget* titlebar = gtk_window_get_titlebar (gtk_window);
737747 if (titlebar) {
738748 title_bar_height = gtk_widget_get_allocated_height (titlebar);
739749 }
740750 }
741751
742- rectangle.x = static_cast <int >(position.x - frame_rectangle.x );
743- rectangle.y = static_cast <int >(position.y - frame_rectangle.y + title_bar_height);
752+ // Get device pixel ratio for DPI scaling
753+ double device_pixel_ratio = 1.0 ;
754+ GdkScreen* screen = gdk_window_get_screen (gdk_window);
755+ if (screen) {
756+ // Get scale factor (typically 1.0 for standard DPI, 2.0 for HiDPI)
757+ device_pixel_ratio = gdk_screen_get_resolution (screen) / 96.0 ;
758+ if (device_pixel_ratio <= 0.0 ) {
759+ device_pixel_ratio = 1.0 ;
760+ }
761+ }
762+
763+ // Convert content-relative coordinates to window-relative coordinates
764+ // Apply DPI scaling, then adjust for window position and frame extents
765+ rectangle.x = static_cast <int >((position.x * device_pixel_ratio) + window_x - frame_rectangle.x );
766+ rectangle.y = static_cast <int >((position.y * device_pixel_ratio) + window_y - frame_rectangle.y + title_bar_height);
744767 } else {
745768 // Relative to rectangle (no window) - use root window coordinates
746769 rectangle.x = static_cast <int >(position.x );
0 commit comments