diff options
author | Matthias Clasen <mclasen@redhat.com> | 2011-12-18 14:02:55 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-12-18 14:29:16 -0500 |
commit | c6df2828b7ca6b65b7ab3c328ebb96bd78c087ee (patch) | |
tree | 19922b74f44281c5d4ec3733437523d6b0340e11 | |
parent | 74cff292d505f8855e78ab0fc37c6ff380d447ca (diff) | |
download | gtk+-c6df2828b7ca6b65b7ab3c328ebb96bd78c087ee.tar.gz |
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
-rw-r--r-- | docs/reference/gdk/gdk3-sections.txt | 1 | ||||
-rw-r--r-- | gdk/broadway/gdkscreen-broadway.c | 1 | ||||
-rw-r--r-- | gdk/gdk.symbols | 1 | ||||
-rw-r--r-- | gdk/gdkscreen.c | 35 | ||||
-rw-r--r-- | gdk/gdkscreen.h | 14 | ||||
-rw-r--r-- | gdk/gdkscreenprivate.h | 3 | ||||
-rw-r--r-- | gdk/quartz/gdkscreen-quartz.c | 1 | ||||
-rw-r--r-- | gdk/wayland/gdkscreen-wayland.c | 1 | ||||
-rw-r--r-- | gdk/win32/gdkscreen-win32.c | 3 | ||||
-rw-r--r-- | gdk/x11/gdkscreen-x11.c | 108 |
10 files changed, 160 insertions, 8 deletions
diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt index 6204900377..ca4173bf7a 100644 --- a/docs/reference/gdk/gdk3-sections.txt +++ b/docs/reference/gdk/gdk3-sections.txt @@ -199,6 +199,7 @@ gdk_screen_make_display_name gdk_screen_get_n_monitors gdk_screen_get_primary_monitor gdk_screen_get_monitor_geometry +gdk_screen_get_monitor_workarea gdk_screen_get_monitor_at_point gdk_screen_get_monitor_at_window gdk_screen_get_monitor_height_mm diff --git a/gdk/broadway/gdkscreen-broadway.c b/gdk/broadway/gdkscreen-broadway.c index 77b7a8863e..899ba9f729 100644 --- a/gdk/broadway/gdkscreen-broadway.c +++ b/gdk/broadway/gdkscreen-broadway.c @@ -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_plug_name = gdk_broadway_screen_get_monitor_plug_name; 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->make_display_name = gdk_broadway_screen_make_display_name; screen_class->get_active_window = gdk_broadway_screen_get_active_window; diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 4222d69a28..e6e366b401 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -271,6 +271,7 @@ gdk_screen_get_height_mm gdk_screen_get_monitor_at_point gdk_screen_get_monitor_at_window gdk_screen_get_monitor_geometry +gdk_screen_get_monitor_workarea gdk_screen_get_monitor_height_mm gdk_screen_get_monitor_plug_name gdk_screen_get_monitor_width_mm diff --git a/gdk/gdkscreen.c b/gdk/gdkscreen.c index c1de0f64e9..9493e168ff 100644 --- a/gdk/gdkscreen.c +++ b/gdk/gdkscreen.c @@ -750,12 +750,16 @@ gdk_screen_get_monitor_plug_name (GdkScreen *screen, /** * gdk_screen_get_monitor_geometry: * @screen: a #GdkScreen - * @monitor_num: the monitor number, between 0 and gdk_screen_get_n_monitors (screen) - * @dest: (out) (allow-none): a #GdkRectangle to be filled with the monitor geometry + * @monitor_num: the monitor number + * @dest: (out) (allow-none): a #GdkRectangle to be filled with + * the monitor geometry * * Retrieves the #GdkRectangle representing the size and position of * 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 * gdk_screen_get_width() and gdk_screen_get_height(). * @@ -770,6 +774,33 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen, } /** + * 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: * @screen: the relevant #GdkScreen. * diff --git a/gdk/gdkscreen.h b/gdk/gdkscreen.h index 0f16a8f0f6..a48c48bfe1 100644 --- a/gdk/gdkscreen.h +++ b/gdk/gdkscreen.h @@ -57,11 +57,15 @@ GList * gdk_screen_list_visuals (GdkScreen *screen); GList * gdk_screen_get_toplevel_windows (GdkScreen *screen); gchar * gdk_screen_make_display_name (GdkScreen *screen); -gint gdk_screen_get_n_monitors (GdkScreen *screen); -gint gdk_screen_get_primary_monitor (GdkScreen *screen); -void gdk_screen_get_monitor_geometry (GdkScreen *screen, - gint monitor_num, - GdkRectangle *dest); +gint gdk_screen_get_n_monitors (GdkScreen *screen); +gint gdk_screen_get_primary_monitor (GdkScreen *screen); +void gdk_screen_get_monitor_geometry (GdkScreen *screen, + gint monitor_num, + 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 x, gint y); diff --git a/gdk/gdkscreenprivate.h b/gdk/gdkscreenprivate.h index 42d03f259d..5ce9f07840 100644 --- a/gdk/gdkscreenprivate.h +++ b/gdk/gdkscreenprivate.h @@ -62,6 +62,9 @@ struct _GdkScreenClass void (* get_monitor_geometry) (GdkScreen *screen, gint monitor_num, GdkRectangle *dest); + void (* get_monitor_workarea) (GdkScreen *screen, + gint monitor_num, + GdkRectangle *dest); GList * (* list_visuals) (GdkScreen *screen); GdkVisual * (* get_system_visual) (GdkScreen *screen); GdkVisual * (* get_rgba_visual) (GdkScreen *screen); diff --git a/gdk/quartz/gdkscreen-quartz.c b/gdk/quartz/gdkscreen-quartz.c index 678a947243..d104571ce6 100644 --- a/gdk/quartz/gdkscreen-quartz.c +++ b/gdk/quartz/gdkscreen-quartz.c @@ -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_plug_name = gdk_quartz_screen_get_monitor_plug_name; 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->make_display_name = gdk_quartz_screen_make_display_name; screen_class->get_active_window = gdk_quartz_screen_get_active_window; diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c index cf7ef90349..310fc15a72 100644 --- a/gdk/wayland/gdkscreen-wayland.c +++ b/gdk/wayland/gdkscreen-wayland.c @@ -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_plug_name = gdk_wayland_screen_get_monitor_plug_name; 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_rgba_visual = gdk_wayland_screen_get_rgba_visual; screen_class->is_composited = gdk_wayland_screen_is_composited; diff --git a/gdk/win32/gdkscreen-win32.c b/gdk/win32/gdkscreen-win32.c index d7a5815bf5..457858a2e7 100644 --- a/gdk/win32/gdkscreen-win32.c +++ b/gdk/win32/gdkscreen-win32.c @@ -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_plug_name = gdk_win32_screen_get_monitor_plug_name; 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_rgba_visual = gdk_win32_screen_get_rgba_visual; 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_visual_types = _gdk_win32_screen_query_visual_types; screen_class->list_visuals = _gdk_win32_screen_list_visuals; -}
\ No newline at end of file +} diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index fc3adaddd2..5574f639e0 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -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; |