Add gdk_screen_get_monitor_workarea
The function returns the part of a monitors area that should be used for positioning popups, menus, etc. The only non-trivial implementation atm is in the X backend, all the other backends just return the full monitor area. The X implementation is currently suboptimal, since it requires roundtrips to collect the necessary information. It should be changed to monitor the properties for changes, when XFixes allows to monitor individual properties. https://bugzilla.gnome.org/show_bug.cgi?id=641999
This commit is contained in:
		| @ -305,6 +305,113 @@ gdk_x11_screen_get_monitor_geometry (GdkScreen    *screen, | ||||
|     *dest = x11_screen->monitors[monitor_num].geometry; | ||||
| } | ||||
|  | ||||
| static int | ||||
| get_current_desktop (GdkScreen *screen) | ||||
| { | ||||
|   Display *display; | ||||
|   Window win; | ||||
|   Atom current_desktop, type; | ||||
|   int format; | ||||
|   unsigned long n_items, bytes_after; | ||||
|   unsigned char *data_return = NULL; | ||||
|   int workspace = 0; | ||||
|  | ||||
|   display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen)); | ||||
|   win = XRootWindow (display, GDK_SCREEN_XNUMBER (screen)); | ||||
|  | ||||
|   current_desktop = XInternAtom (display, "_NET_CURRENT_DESKTOP", True); | ||||
|  | ||||
|   XGetWindowProperty (display, | ||||
|                       win, | ||||
|                       current_desktop, | ||||
|                       0, G_MAXLONG, | ||||
|                       False, XA_CARDINAL, | ||||
|                       &type, &format, &n_items, &bytes_after, | ||||
|                       &data_return); | ||||
|  | ||||
|   if (type == XA_CARDINAL && format == 32 && n_items > 0) | ||||
|     workspace = (int) data_return[0]; | ||||
|  | ||||
|   if (data_return) | ||||
|     XFree (data_return); | ||||
|  | ||||
|   return workspace; | ||||
| } | ||||
|  | ||||
| static void | ||||
| get_work_area (GdkScreen    *screen, | ||||
|                GdkRectangle *area) | ||||
| { | ||||
|   Atom            workarea; | ||||
|   Atom            type; | ||||
|   Window          win; | ||||
|   int             format; | ||||
|   gulong          num; | ||||
|   gulong          leftovers; | ||||
|   gulong          max_len = 4 * 32; | ||||
|   guchar         *ret_workarea; | ||||
|   long           *workareas; | ||||
|   int             result; | ||||
|   int             disp_screen; | ||||
|   int             desktop; | ||||
|   Display        *display; | ||||
|  | ||||
|   display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen)); | ||||
|   disp_screen = GDK_SCREEN_XNUMBER (screen); | ||||
|   workarea = XInternAtom (display, "_NET_WORKAREA", True); | ||||
|  | ||||
|   /* Defaults in case of error */ | ||||
|   area->x = 0; | ||||
|   area->y = 0; | ||||
|   area->width = gdk_screen_get_width (screen); | ||||
|   area->height = gdk_screen_get_height (screen); | ||||
|  | ||||
|   if (workarea == None) | ||||
|     return; | ||||
|  | ||||
|   win = XRootWindow (display, disp_screen); | ||||
|   result = XGetWindowProperty (display, | ||||
|                                win, | ||||
|                                workarea, | ||||
|                                0, | ||||
|                                max_len, | ||||
|                                False, | ||||
|                                AnyPropertyType, | ||||
|                                &type, | ||||
|                                &format, | ||||
|                                &num, | ||||
|                                &leftovers, | ||||
|                                &ret_workarea); | ||||
|   if (result != Success || | ||||
|       type == None || | ||||
|       format == 0 || | ||||
|       leftovers || | ||||
|       num % 4 != 0) | ||||
|     return; | ||||
|  | ||||
|   desktop = get_current_desktop (screen); | ||||
|  | ||||
|   workareas = (long *) ret_workarea; | ||||
|   area->x = workareas[desktop * 4]; | ||||
|   area->y = workareas[desktop * 4 + 1]; | ||||
|   area->width = workareas[desktop * 4 + 2]; | ||||
|   area->height = workareas[desktop * 4 + 3]; | ||||
|  | ||||
|   XFree (ret_workarea); | ||||
| } | ||||
|  | ||||
| static void | ||||
| gdk_x11_screen_get_monitor_workarea (GdkScreen    *screen, | ||||
|                                      gint          monitor_num, | ||||
|                                      GdkRectangle *dest) | ||||
| { | ||||
|   GdkRectangle workarea; | ||||
|  | ||||
|   gdk_x11_screen_get_monitor_geometry (screen, monitor_num, dest); | ||||
|   get_work_area (screen, &workarea); | ||||
|   gdk_rectangle_intersect (&workarea, dest, dest); | ||||
| } | ||||
|  | ||||
| static GdkVisual * | ||||
| gdk_x11_screen_get_rgba_visual (GdkScreen *screen) | ||||
| { | ||||
| @ -1603,6 +1710,7 @@ gdk_x11_screen_class_init (GdkX11ScreenClass *klass) | ||||
|   screen_class->get_monitor_height_mm = gdk_x11_screen_get_monitor_height_mm; | ||||
|   screen_class->get_monitor_plug_name = gdk_x11_screen_get_monitor_plug_name; | ||||
|   screen_class->get_monitor_geometry = gdk_x11_screen_get_monitor_geometry; | ||||
|   screen_class->get_monitor_workarea = gdk_x11_screen_get_monitor_workarea; | ||||
|   screen_class->get_system_visual = _gdk_x11_screen_get_system_visual; | ||||
|   screen_class->get_rgba_visual = gdk_x11_screen_get_rgba_visual; | ||||
|   screen_class->is_composited = gdk_x11_screen_is_composited; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Matthias Clasen
					Matthias Clasen