mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
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:
parent
74cff292d5
commit
c6df2828b7
@ -199,6 +199,7 @@ gdk_screen_make_display_name
|
|||||||
gdk_screen_get_n_monitors
|
gdk_screen_get_n_monitors
|
||||||
gdk_screen_get_primary_monitor
|
gdk_screen_get_primary_monitor
|
||||||
gdk_screen_get_monitor_geometry
|
gdk_screen_get_monitor_geometry
|
||||||
|
gdk_screen_get_monitor_workarea
|
||||||
gdk_screen_get_monitor_at_point
|
gdk_screen_get_monitor_at_point
|
||||||
gdk_screen_get_monitor_at_window
|
gdk_screen_get_monitor_at_window
|
||||||
gdk_screen_get_monitor_height_mm
|
gdk_screen_get_monitor_height_mm
|
||||||
|
@ -321,6 +321,7 @@ gdk_broadway_screen_class_init (GdkBroadwayScreenClass *klass)
|
|||||||
screen_class->get_monitor_height_mm = gdk_broadway_screen_get_monitor_height_mm;
|
screen_class->get_monitor_height_mm = gdk_broadway_screen_get_monitor_height_mm;
|
||||||
screen_class->get_monitor_plug_name = gdk_broadway_screen_get_monitor_plug_name;
|
screen_class->get_monitor_plug_name = gdk_broadway_screen_get_monitor_plug_name;
|
||||||
screen_class->get_monitor_geometry = gdk_broadway_screen_get_monitor_geometry;
|
screen_class->get_monitor_geometry = gdk_broadway_screen_get_monitor_geometry;
|
||||||
|
screen_class->get_monitor_workarea = gdk_broadway_screen_get_monitor_geometry;
|
||||||
screen_class->is_composited = gdk_broadway_screen_is_composited;
|
screen_class->is_composited = gdk_broadway_screen_is_composited;
|
||||||
screen_class->make_display_name = gdk_broadway_screen_make_display_name;
|
screen_class->make_display_name = gdk_broadway_screen_make_display_name;
|
||||||
screen_class->get_active_window = gdk_broadway_screen_get_active_window;
|
screen_class->get_active_window = gdk_broadway_screen_get_active_window;
|
||||||
|
@ -271,6 +271,7 @@ gdk_screen_get_height_mm
|
|||||||
gdk_screen_get_monitor_at_point
|
gdk_screen_get_monitor_at_point
|
||||||
gdk_screen_get_monitor_at_window
|
gdk_screen_get_monitor_at_window
|
||||||
gdk_screen_get_monitor_geometry
|
gdk_screen_get_monitor_geometry
|
||||||
|
gdk_screen_get_monitor_workarea
|
||||||
gdk_screen_get_monitor_height_mm
|
gdk_screen_get_monitor_height_mm
|
||||||
gdk_screen_get_monitor_plug_name
|
gdk_screen_get_monitor_plug_name
|
||||||
gdk_screen_get_monitor_width_mm
|
gdk_screen_get_monitor_width_mm
|
||||||
|
@ -750,12 +750,16 @@ gdk_screen_get_monitor_plug_name (GdkScreen *screen,
|
|||||||
/**
|
/**
|
||||||
* gdk_screen_get_monitor_geometry:
|
* gdk_screen_get_monitor_geometry:
|
||||||
* @screen: a #GdkScreen
|
* @screen: a #GdkScreen
|
||||||
* @monitor_num: the monitor number, between 0 and gdk_screen_get_n_monitors (screen)
|
* @monitor_num: the monitor number
|
||||||
* @dest: (out) (allow-none): a #GdkRectangle to be filled with the monitor geometry
|
* @dest: (out) (allow-none): a #GdkRectangle to be filled with
|
||||||
|
* the monitor geometry
|
||||||
*
|
*
|
||||||
* Retrieves the #GdkRectangle representing the size and position of
|
* Retrieves the #GdkRectangle representing the size and position of
|
||||||
* the individual monitor within the entire screen area.
|
* the individual monitor within the entire screen area.
|
||||||
*
|
*
|
||||||
|
* Monitor numbers start at 0. To obtain the number of monitors of
|
||||||
|
* @screen, use gdk_screen_get_n_monitors().
|
||||||
|
*
|
||||||
* Note that the size of the entire screen area can be retrieved via
|
* Note that the size of the entire screen area can be retrieved via
|
||||||
* gdk_screen_get_width() and gdk_screen_get_height().
|
* gdk_screen_get_width() and gdk_screen_get_height().
|
||||||
*
|
*
|
||||||
@ -769,6 +773,33 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen,
|
|||||||
GDK_SCREEN_GET_CLASS(screen)->get_monitor_geometry (screen, monitor_num, dest);
|
GDK_SCREEN_GET_CLASS(screen)->get_monitor_geometry (screen, monitor_num, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_screen_get_monitor_workarea:
|
||||||
|
* @screen: a #GdkScreen
|
||||||
|
* @monitor_num: the monitor number
|
||||||
|
* @dest: (out) (allow-none): a #GdkRectangle to be filled with
|
||||||
|
* the monitor workarea
|
||||||
|
*
|
||||||
|
* Retrieves the #GdkRectangle representing the size and position of
|
||||||
|
* the "work area" on a monitor within the entire screen area.
|
||||||
|
*
|
||||||
|
* The work area should be considered when positioning menus and
|
||||||
|
* similar popups, to avoid placing them below panels, docks or other
|
||||||
|
* desktop components.
|
||||||
|
*
|
||||||
|
* Monitor numbers start at 0. To obtain the number of monitors of
|
||||||
|
* @screen, use gdk_screen_get_n_monitors().
|
||||||
|
*
|
||||||
|
* Since: 3.4
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gdk_screen_get_monitor_workarea (GdkScreen *screen,
|
||||||
|
gint monitor_num,
|
||||||
|
GdkRectangle *dest)
|
||||||
|
{
|
||||||
|
GDK_SCREEN_GET_CLASS(screen)->get_monitor_workarea (screen, monitor_num, dest);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_screen_list_visuals:
|
* gdk_screen_list_visuals:
|
||||||
* @screen: the relevant #GdkScreen.
|
* @screen: the relevant #GdkScreen.
|
||||||
|
@ -57,11 +57,15 @@ GList * gdk_screen_list_visuals (GdkScreen *screen);
|
|||||||
GList * gdk_screen_get_toplevel_windows (GdkScreen *screen);
|
GList * gdk_screen_get_toplevel_windows (GdkScreen *screen);
|
||||||
gchar * gdk_screen_make_display_name (GdkScreen *screen);
|
gchar * gdk_screen_make_display_name (GdkScreen *screen);
|
||||||
|
|
||||||
gint gdk_screen_get_n_monitors (GdkScreen *screen);
|
gint gdk_screen_get_n_monitors (GdkScreen *screen);
|
||||||
gint gdk_screen_get_primary_monitor (GdkScreen *screen);
|
gint gdk_screen_get_primary_monitor (GdkScreen *screen);
|
||||||
void gdk_screen_get_monitor_geometry (GdkScreen *screen,
|
void gdk_screen_get_monitor_geometry (GdkScreen *screen,
|
||||||
gint monitor_num,
|
gint monitor_num,
|
||||||
GdkRectangle *dest);
|
GdkRectangle *dest);
|
||||||
|
void gdk_screen_get_monitor_workarea (GdkScreen *screen,
|
||||||
|
gint monitor_num,
|
||||||
|
GdkRectangle *area);
|
||||||
|
|
||||||
gint gdk_screen_get_monitor_at_point (GdkScreen *screen,
|
gint gdk_screen_get_monitor_at_point (GdkScreen *screen,
|
||||||
gint x,
|
gint x,
|
||||||
gint y);
|
gint y);
|
||||||
|
@ -62,6 +62,9 @@ struct _GdkScreenClass
|
|||||||
void (* get_monitor_geometry) (GdkScreen *screen,
|
void (* get_monitor_geometry) (GdkScreen *screen,
|
||||||
gint monitor_num,
|
gint monitor_num,
|
||||||
GdkRectangle *dest);
|
GdkRectangle *dest);
|
||||||
|
void (* get_monitor_workarea) (GdkScreen *screen,
|
||||||
|
gint monitor_num,
|
||||||
|
GdkRectangle *dest);
|
||||||
GList * (* list_visuals) (GdkScreen *screen);
|
GList * (* list_visuals) (GdkScreen *screen);
|
||||||
GdkVisual * (* get_system_visual) (GdkScreen *screen);
|
GdkVisual * (* get_system_visual) (GdkScreen *screen);
|
||||||
GdkVisual * (* get_rgba_visual) (GdkScreen *screen);
|
GdkVisual * (* get_rgba_visual) (GdkScreen *screen);
|
||||||
|
@ -462,6 +462,7 @@ gdk_quartz_screen_class_init (GdkQuartzScreenClass *klass)
|
|||||||
screen_class->get_monitor_height_mm = gdk_quartz_screen_get_monitor_height_mm;
|
screen_class->get_monitor_height_mm = gdk_quartz_screen_get_monitor_height_mm;
|
||||||
screen_class->get_monitor_plug_name = gdk_quartz_screen_get_monitor_plug_name;
|
screen_class->get_monitor_plug_name = gdk_quartz_screen_get_monitor_plug_name;
|
||||||
screen_class->get_monitor_geometry = gdk_quartz_screen_get_monitor_geometry;
|
screen_class->get_monitor_geometry = gdk_quartz_screen_get_monitor_geometry;
|
||||||
|
screen_class->get_monitor_workarea = gdk_quartz_screen_get_monitor_geometry;
|
||||||
screen_class->is_composited = gdk_quartz_screen_is_composited;
|
screen_class->is_composited = gdk_quartz_screen_is_composited;
|
||||||
screen_class->make_display_name = gdk_quartz_screen_make_display_name;
|
screen_class->make_display_name = gdk_quartz_screen_make_display_name;
|
||||||
screen_class->get_active_window = gdk_quartz_screen_get_active_window;
|
screen_class->get_active_window = gdk_quartz_screen_get_active_window;
|
||||||
|
@ -502,6 +502,7 @@ _gdk_screen_wayland_class_init (GdkScreenWaylandClass *klass)
|
|||||||
screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
|
screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
|
||||||
screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
|
screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
|
||||||
screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
|
screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
|
||||||
|
screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
|
||||||
screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
|
screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
|
||||||
screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
|
screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
|
||||||
screen_class->is_composited = gdk_wayland_screen_is_composited;
|
screen_class->is_composited = gdk_wayland_screen_is_composited;
|
||||||
|
@ -222,6 +222,7 @@ gdk_win32_screen_class_init (GdkWin32ScreenClass *klass)
|
|||||||
screen_class->get_monitor_height_mm = gdk_win32_screen_get_monitor_height_mm;
|
screen_class->get_monitor_height_mm = gdk_win32_screen_get_monitor_height_mm;
|
||||||
screen_class->get_monitor_plug_name = gdk_win32_screen_get_monitor_plug_name;
|
screen_class->get_monitor_plug_name = gdk_win32_screen_get_monitor_plug_name;
|
||||||
screen_class->get_monitor_geometry = gdk_win32_screen_get_monitor_geometry;
|
screen_class->get_monitor_geometry = gdk_win32_screen_get_monitor_geometry;
|
||||||
|
screen_class->get_monitor_workarea = gdk_win32_screen_get_monitor_geometry;
|
||||||
screen_class->get_system_visual = _gdk_win32_screen_get_system_visual;
|
screen_class->get_system_visual = _gdk_win32_screen_get_system_visual;
|
||||||
screen_class->get_rgba_visual = gdk_win32_screen_get_rgba_visual;
|
screen_class->get_rgba_visual = gdk_win32_screen_get_rgba_visual;
|
||||||
screen_class->is_composited = gdk_win32_screen_is_composited;
|
screen_class->is_composited = gdk_win32_screen_is_composited;
|
||||||
@ -238,4 +239,4 @@ gdk_win32_screen_class_init (GdkWin32ScreenClass *klass)
|
|||||||
screen_class->query_depths = _gdk_win32_screen_query_depths;
|
screen_class->query_depths = _gdk_win32_screen_query_depths;
|
||||||
screen_class->query_visual_types = _gdk_win32_screen_query_visual_types;
|
screen_class->query_visual_types = _gdk_win32_screen_query_visual_types;
|
||||||
screen_class->list_visuals = _gdk_win32_screen_list_visuals;
|
screen_class->list_visuals = _gdk_win32_screen_list_visuals;
|
||||||
}
|
}
|
||||||
|
@ -305,6 +305,113 @@ gdk_x11_screen_get_monitor_geometry (GdkScreen *screen,
|
|||||||
*dest = x11_screen->monitors[monitor_num].geometry;
|
*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 *
|
static GdkVisual *
|
||||||
gdk_x11_screen_get_rgba_visual (GdkScreen *screen)
|
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_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_plug_name = gdk_x11_screen_get_monitor_plug_name;
|
||||||
screen_class->get_monitor_geometry = gdk_x11_screen_get_monitor_geometry;
|
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_system_visual = _gdk_x11_screen_get_system_visual;
|
||||||
screen_class->get_rgba_visual = gdk_x11_screen_get_rgba_visual;
|
screen_class->get_rgba_visual = gdk_x11_screen_get_rgba_visual;
|
||||||
screen_class->is_composited = gdk_x11_screen_is_composited;
|
screen_class->is_composited = gdk_x11_screen_is_composited;
|
||||||
|
Loading…
Reference in New Issue
Block a user