Подробности
[В начало]
Проблема в реализации № D0129
Краткое описание
Поведение функции gdk_screen_get_monitor_at_window() не соответствует требованиям стандарта LSB 3.2
Подробное описание
В документации GDK-2.8.2, на которую ссылается стандарт LSB 3.2, функция gdk_screen_get_monitor_at_window должна вернуть номер монитора, в котором находится большая часть окна.
В действительности gdk_screen_get_monitor_at_window возвращает номер монитора, не соответствующий ожидаемому.
Причина этого, по нашему мнению, заключается в следующем фрагменте исходного кода функции:
gint gdk_screen_get_monitor_at_window (GdkScreen *screen, GdkWindow *window) { ... gdk_window_get_geometry (window, &win_rect.x, &win_rect.y,&иin_rect.width, &win_rect.height, NULL); gdk_window_get_origin (window, &win_rect.x, &win_rect.y); ... gdk_rectangle_intersect (&win_rect, &tmp_monitor, &intersect); ... }Проблема здесь в том, что в вызове функции gdk_window_get_origin используется те же самые координаты win_rect, которые изменяются после вызова gdk_window_get_origin.
Раздел стандарта
Linux Standard Base Desktop Specification 3.2. Chapter 15. Libraries. 15.21.1.1. Interfaces for GTK Drawing toolkit., который ссылается на http://www.gtk.org/api/2.6/gdk/GdkScreen.html#id2663323
Пример
#include <gdk/gdk.h> #include <glib.h> #include <stdio.h> int getMonitorWidth(GdkScreen *screen, int monitorNum) { GdkRectangle monitor; gdk_screen_get_monitor_geometry (screen, monitorNum, &monitor); return monitor.width; } int main (int argc, char **argv) { #define X_LOCATION getMonitorWidth(screen, 0) - 10 #define Y_LOCATION 10 #define WIDTH 200 #define HEIGHT 200 #define EXPECTED 1 GdkWindow *window = NULL; GdkWindowAttr attr; GdkScreen *screen = NULL; gdk_init(&argc, &argv); screen = gdk_screen_get_default(); gint num_monitors = gdk_screen_get_n_monitors (screen); attr.title = "NEW_WINDOW"; attr.x = X_LOCATION; attr.y = Y_LOCATION; attr.width = WIDTH; attr.height = HEIGHT; attr.wclass = GDK_INPUT_OUTPUT; attr.window_type = GDK_WINDOW_TOPLEVEL; window = gdk_window_new(NULL, &attr, GDK_WA_X | GDK_WA_Y |GDK_WA_TITLE); if (window == NULL) { printf("The gdk_window_new function returned NULL, unable to create GdkWindow.\n"); return 0; } gdk_window_show(window); gint monitorNum = gdk_screen_get_monitor_at_window(screen, window); printf("monitorNum = %d", monitorNum); printf("Expected = %d, received = %d", EXPECTED, monitorNum); if(window != NULL) { gdk_window_destroy(window); } return 0; }
Способы устранения
Следует вызывать gdk_window_get_origin с другими параметрами, скажем, orig_rect.
@@ -1,13 +1,13 @@ gint gsk_screen_get_monitor_at_window (GdkScreen *screen, GdkWindow *window) { gint num_monitors, i, area = 0, screen_num = -1; - GdkRectangle win_rect; + GdkRectangle win_rect, orig_rect; g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); gdk_window_get_geometry (window, &win_rect.x, &win_rect.y, &win_rect.width, &win_rect.height, NULL); - gdk_window_get_origin (window, &win_rect.x, &win_rect.y); + gdk_window_get_origin (window, &orig_rect.x, &orig_rect.y); num_monitors = gdk_screen_get_n_monitors (screen); @@ -27,6 +27,6 @@ if (screen_num >= 0) return screen_num; else - return get_nearest_monitor (screen, win_rect.x + win_rect.width / 2, - win_rect.y + win_rect.height / 2); + return get_nearest_monitor (screen, orig_rect.x + win_rect.width / 2, + orig_rect.y + win_rect.height / 2); }
Компонент
gtk+ 2.19.x or early
Окружение
Прочее
The problem was discovered under the system with two monitors connected to each other horizontally.
Принято
Gnome Bugzilla, 583879
[В начало]