Details

[Home]

Issue of the Implementation # D0129

Brief

The implementation of this function does not correspond to standard's requirements

Detailed Description

The function gdk_screen_get_monitor_at_window (GDK-2.8.2 documentation) must return the number of the monitor in which the largest area ob the bounding rectangle resides. But it returns the number of the monitor which is not expected.

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);
   ...
}
The problem: gdk_window_get_origin uses just the same coordinates win_rect. win_rect are being overrided after the call gdk_window_get_origin.

Problem location(s) in the standard

Linux Standard Base Desktop Specification 3.2. Chapter 15. Libraries. 15.21.1.1. Interfaces for GTK Drawing toolkit. that refers http://www.gtk.org/api/2.6/gdk/GdkScreen.html#id2663323

Example

#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;
}

Possible solutions

gdk_window_get_origin should be called with parameters orig_rect.x, orig_rect.y.

@@ -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);
 }

Component

gtk+ 2.19.x or early

Environment

Other

The problem was discovered under the system with two monitors connected to each other horizontally.

Accepted

Gnome Bugzilla, 583879

[Home]