[maemo-commits] [maemo-commits] r12940 - projects/haf/trunk/gtk+/gtk
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Tue Jul 31 12:56:21 EEST 2007
- Previous message: [maemo-commits] r12939 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r12941 - projects/haf/trunk/gtk+/gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: xan
Date: 2007-07-31 12:56:19 +0300 (Tue, 31 Jul 2007)
New Revision: 12940
Modified:
projects/haf/trunk/gtk+/gtk/gtkentrycompletion.c
Log:
Use _NET_INPUT_AREAS to decide GtkEntryCompletion popup positioning.
The matchbox version on Sardine has a new X property for the root window
called _NET_INPUT_AREAS. It's supposed to contain an array of rectangles
which are reserved for user interaction and should never be obscured
(Note: the current matchbox impl. only seems to supports one input area at the time,
I'm assuming this is a bug and have developed the general case. When Tapani
is back I'll poke him about this).
I've modified the GtkEntryCompletion popup position code to:
* Get a list of the available input areas.
* Compute the intersections with the rectangle composed with
X = entry's X, Y = 0, WIDTH = entry's WIDTH, HEIGHT = monitors' HEIGHT
* From that data gather which one is the nearest intersecting area above
and below the entry.
* Based on the distances to those areas, decide where to show the popup.
Known problems: I don't really know what to do when there's no space either
way to show the popup.
Modified: projects/haf/trunk/gtk+/gtk/gtkentrycompletion.c
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtkentrycompletion.c 2007-07-31 09:56:10 UTC (rev 12939)
+++ projects/haf/trunk/gtk+/gtk/gtkentrycompletion.c 2007-07-31 09:56:19 UTC (rev 12940)
@@ -40,6 +40,10 @@
#include <string.h>
+#if defined(MAEMO_CHANGES) && defined(GDK_WINDOWING_X11)
+#include "x11/gdkx.h"
+#include <X11/Xatom.h>
+#endif
/* signals */
enum
@@ -1385,7 +1389,103 @@
x = monitor.x;
else if (x + popup_req.width > monitor.x + monitor.width)
x = monitor.x + monitor.width - popup_req.width;
-
+
+#if defined(MAEMO_CHANGES) && defined(GDK_WINDOWING_X11)
+ GdkWindow *window = completion->priv->popup_window->window;
+ GdkDisplay *display = gdk_drawable_get_display (window);
+ Atom type_return;
+ int format_return, ret_val, n_rects;
+ gulong nitems_return, bytes_after_return;
+ guchar *data;
+ guint32 *val;
+
+ ret_val = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (gtk_widget_get_root_window (completion->priv->popup_window)),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_INPUT_AREAS"),
+ 0, G_MAXULONG,
+ False,
+ XA_CARDINAL,
+ &type_return, &format_return, &nitems_return, &bytes_after_return,
+ &data);
+
+ n_rects = nitems_return/4;
+
+ if (ret_val == Success && n_rects > 0)
+ {
+ int i, j;
+ GdkRectangle widget_rect;
+ GdkRectangle *rectangles = (GdkRectangle*)g_slice_alloc (sizeof(GdkRectangle)*n_rects);
+ gint root_x, root_y;
+ GdkRectangle *top = NULL, *bottom = NULL;
+ gint to_top = -1, to_bottom = -1;
+
+ val = (guint32*)data;
+
+ for (i = 0, j = 0; i < nitems_return; i+=4, j++)
+ {
+ rectangles[j].x = val[i];
+ rectangles[j].y = val[i+1];
+ rectangles[j].width = val[i+2];
+ rectangles[j].height = val[i+3];
+ }
+
+ XFree (data);
+
+ gdk_window_get_origin (completion->priv->entry->window, &root_x, &root_y);
+
+ widget_rect.x = root_x;
+ widget_rect.y = 0;
+ widget_rect.width = completion->priv->entry->allocation.width;
+ widget_rect.height = monitor.height;
+
+ for (i = 0; i < n_rects; i++)
+ {
+ GdkRectangle dest;
+
+ if (gdk_rectangle_intersect (&widget_rect, &rectangles[i], &dest))
+ {
+ if (rectangles[i].y < root_y &&
+ (top == NULL || top->y < rectangles[i].y))
+ {
+ top = &rectangles[i];
+ }
+ else if (rectangles[i].y > root_y &&
+ (bottom == NULL || bottom->y > rectangles[i].y))
+ {
+ bottom = &rectangles[i];
+ }
+ }
+ }
+ /* Which one is nearer */
+ if (top)
+ to_top = root_y - (top->y + top->height);
+ else
+ to_top = root_y;
+
+ if (bottom)
+ to_bottom = bottom->y - (root_y + completion->priv->entry->allocation.y);
+ else
+ to_bottom = monitor.height - (root_y + completion->priv->entry->allocation.y);
+
+ if (popup_req.height <= to_bottom)
+ {
+ above = FALSE;
+ y += entry_req.height;
+ }
+ else if (popup_req.height <= to_top)
+ {
+ above = TRUE;
+ y -= popup_req.height;
+ }
+ else
+ {
+ /* Doesn't fit (what should we do?) */
+ }
+
+ g_slice_free1 (sizeof(GdkRectangle)*n_rects, rectangles);
+ }
+ else
+#endif /* MAEMO_CHANGES && GDK_WINDOWING_X11 */
if (y + entry_req.height + popup_req.height <= monitor.y + monitor.height ||
y - monitor.y < (monitor.y + monitor.height) - (y + entry_req.height))
{
- Previous message: [maemo-commits] r12939 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r12941 - projects/haf/trunk/gtk+/gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
