[maemo-commits] [maemo-commits] r11187 - in projects/haf/trunk/hildon-desktop: . libhildondesktop
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Fri Apr 20 18:08:49 EEST 2007
- Previous message: [maemo-commits] r11186 - in projects/haf/trunk/hail: . docs
- Next message: [maemo-commits] r11188 - in projects/haf/trunk/hildon-desktop: . debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: moimart
Date: 2007-04-20 18:08:48 +0300 (Fri, 20 Apr 2007)
New Revision: 11187
Modified:
projects/haf/trunk/hildon-desktop/ChangeLog
projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am
projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c
projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h
Log:
* libhildondesktop/hildon-desktop-popup-window.[ch]:
- Fixed a lot of issues to get it built.
* libhildondesktop/Makefile.am:
- Added HildonDesktopPopupWindow to building batch
* ChangeLog updated.
Modified: projects/haf/trunk/hildon-desktop/ChangeLog
===================================================================
--- projects/haf/trunk/hildon-desktop/ChangeLog 2007-04-20 14:46:29 UTC (rev 11186)
+++ projects/haf/trunk/hildon-desktop/ChangeLog 2007-04-20 15:08:48 UTC (rev 11187)
@@ -1,5 +1,12 @@
-2007-04-17 Johan Bilien <johan.bilien at nokia.com>
+2007-04-20 Moises Martinez <moises.martinez at nokia.com>
+ * libhildondesktop/hildon-desktop-popup-window.[ch]:
+ - Fixed a lot of issues to get it built.
+ * libhildondesktop/Makefile.am:
+ - Added HildonDesktopPopupWindow to building batch
+
+2007-04-20 Johan Bilien <johan.bilien at nokia.com>
+
* libhildondesktop/hildon-home-area.c:
- fixed an infinite loop in some situations.
Fixes: NB#53973
Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am 2007-04-20 14:46:29 UTC (rev 11186)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/Makefile.am 2007-04-20 15:08:48 UTC (rev 11187)
@@ -13,6 +13,7 @@
hildon-desktop-plugin.h \
hildon-desktop-panel-window.h \
hildon-desktop-panel-window-dialog.h \
+ hildon-desktop-popup-window.h \
hildon-desktop-panel.h \
hildon-desktop-multiscreen.h \
hildon-desktop-panel-expandable.h \
@@ -89,6 +90,8 @@
hildon-desktop-panel-window.c \
hildon-desktop-panel-window-dialog.h \
hildon-desktop-panel-window-dialog.c \
+ hildon-desktop-popup-window.h \
+ hildon-desktop-popup-window.c \
hildon-desktop-panel-expandable.h \
hildon-desktop-panel-expandable.c \
hildon-desktop-multiscreen.h \
Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c 2007-04-20 14:46:29 UTC (rev 11186)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c 2007-04-20 15:08:48 UTC (rev 11187)
@@ -25,6 +25,10 @@
#include "hildon-desktop-popup-window.h"
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkwindow.h>
+
#define HILDON_DESKTOP_POPUP_WINDOW_GET_PRIVATE(object) \
(G_TYPE_INSTANCE_GET_PRIVATE ((object), HILDON_DESKTOP_TYPE_POPUP_WINDOW, HildonDesktopPopupWindowPrivate))
@@ -39,7 +43,7 @@
enum
{
- POPUP_N_SIGNALS;
+ POPUP_N_SIGNALS
};
static GObject *hildon_desktop_popup_window_constructor (GType gtype,
@@ -63,35 +67,50 @@
static void hildon_desktop_popup_window_show_all (GtkWidget *widget);
static void hildon_desktop_popup_window_hide_all (GtkWidget *widget);
-static gboolean hildon_desktop_popup_window_focus (GtkWidget *widget);
+static gboolean hildon_desktop_popup_window_enter_notify (GtkWidget *widget, GdkEventCrossing *event);
+static gboolean hildon_desktop_popup_window_leave_notify (GtkWidget *widget, GdkEventCrossing *event);
static gboolean hildon_desktop_popup_window_visibility_notify (GtkWidget *widget,
GdkEventVisibility *event,
gpointer data);
-struct _HildonDesktopPopupWindow
+static gboolean hildon_desktop_popup_window_composited_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event,
+ HildonDesktopPopupWindow *popup);
+
+static gboolean
+hildon_desktop_popup_window_button_release_event (GtkWidget *widget, GdkEventButton *event);
+
+struct _HildonDesktopPopupWindowPrivate
{
GtkWidget **extra_panes;
guint n_extra_panes;
GtkOrientation orientation;
HildonDesktopPopupWindowDirection direction;
-}
+ HDPopupWindowPositionFunc position_func;
+ gpointer position_func_data;
+
+ gboolean have_xgrab;
+
+ GtkWidget *attached_widget;
+};
+
static void
-hildon_desktop_popup_window_init (GObject *object)
+hildon_desktop_popup_window_init (HildonDesktopPopupWindow *popup)
{
- HildonDesktopPopupWindow *popup = HILDON_DESKTOP_POPUP_WINDOW (object);
+ popup->priv = HILDON_DESKTOP_POPUP_WINDOW_GET_PRIVATE (popup);
- popup->priv = HILDON_DESKTOP_POPUP_WINDOW_GET_PRIVATE (object);
-
popup->priv->extra_panes = NULL;
popup->priv->n_extra_panes = 0;
+ popup->priv->have_xgrab = FALSE;
+ popup->priv->attached_widget = NULL;
}
static void
-hildon_desktop_popup_window_class_init (HildonDesktopPopupWindow *popup_class)
+hildon_desktop_popup_window_class_init (HildonDesktopPopupWindowClass *popup_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (popup_class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (popup_class);
@@ -102,17 +121,17 @@
widget_class->enter_notify_event = hildon_desktop_popup_window_enter_notify;
widget_class->leave_notify_event = hildon_desktop_popup_window_leave_notify;
+ widget_class->button_release_event = hildon_desktop_popup_window_button_release_event;
- widget_class->focus = hildon_desktop_popup_window_focus;
widget_class->realize = hildon_desktop_popup_window_realize;
widget_class->unrealize = hildon_desktop_popup_window_unrealize;
- widget_class->show = hildon_desktop_popup_show;
- widget_class->hide = hildon_desktop_popup_hide;
- widget_class->show_all = hildon_desktop_popup_show_all;
- widget_class->hide_all = hildon_desktop_popup_hide_all;
+ widget_class->show = hildon_desktop_popup_window_show;
+ widget_class->hide = hildon_desktop_popup_window_hide;
+ widget_class->show_all = hildon_desktop_popup_window_show_all;
+ widget_class->hide_all = hildon_desktop_popup_window_hide_all;
- g_type_class_add_private (g_object_class, sizeof (HildonDesktopPopupWindowPrivate));
+ g_type_class_add_private (object_class, sizeof (HildonDesktopPopupWindowPrivate));
g_object_class_install_property (object_class,
PROP_POPUP_N_PANES,
@@ -165,25 +184,23 @@
GTK_WINDOW (popup)->type = GTK_WINDOW_POPUP;
- gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_POPUP);
+ gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_MENU);
g_signal_connect (popup,
- "visibility_notify_envent",
+ "visibility-notify-event",
G_CALLBACK (hildon_desktop_popup_window_visibility_notify),
NULL);
gtk_widget_push_composite_child ();
- popup->priv->extra_panes = g_new0 (GtkWindow *, popup->priv->n_extra_panes);
+ popup->priv->extra_panes = g_new0 (GtkWidget *, popup->priv->n_extra_panes);
for (i=0; i < popup->priv->n_extra_panes; i++)
{
popup->priv->extra_panes[i] = gtk_window_new (GTK_WINDOW_POPUP);
- g_signal_connect (popup->priv->extra_panes[i],
- "enter-notify-event",
- G_CALLBACK (hildon_desktop_popup_window_composited_enter_notify),
- (gpointer)popup);
+ gtk_window_set_type_hint (GTK_WINDOW (popup->priv->extra_panes[i]),
+ GDK_WINDOW_TYPE_HINT_MENU);
g_signal_connect (popup->priv->extra_panes[i],
"leave-notify-event",
@@ -272,24 +289,19 @@
gtk_widget_hide_all (popup->priv->extra_panes[i]);
}
-static gboolean
-hildon_desktop_popup_window_focus (GtkWidget *widget)
-{
- /* What focus? */
- return FALSE;
-}
-
static gboolean
hildon_desktop_popup_window_enter_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
HildonDesktopPopupWindow *popup = HILDON_DESKTOP_POPUP_WINDOW (widget);
+ g_debug ("%s enter_notify %p",__FILE__,popup);
/* We have to grab the pointer in here, we should get this when we come from
* a composited window
*/
- return TRUE;
+ return
+ GTK_WIDGET_CLASS (hildon_desktop_popup_window_parent_class)->enter_notify_event (widget, event);
}
static gboolean
@@ -301,21 +313,13 @@
/* We have to ungrab the pointer in here, we should get this when we go to
* a composited window
*/
+ g_debug ("%s leave_notify %p",__FILE__,popup);
- return TRUE;
+ return
+ GTK_WIDGET_CLASS (hildon_desktop_popup_window_parent_class)->leave_notify_event (widget, event);
}
static gboolean
-hildon_desktop_popup_window_composited_enter_notify (GtkWidget *widget,
- GdkEventCrossing *event,
- HildonDesktopPopupWindow *popup)
-{
-
-
- return TRUE;
-}
-
-static gboolean
hildon_desktop_popup_window_composited_leave_notify (GtkWidget *widget,
GdkEventCrossing *event,
HildonDesktopPopupWindow *popup)
@@ -332,15 +336,159 @@
{
HildonDesktopPopupWindow *popup = HILDON_DESKTOP_POPUP_WINDOW (widget);
+ g_debug ("%s visibility_notify %p",__FILE__,popup);
/* We have to close every window when called this but also we have to
* track if our composited windows are not the responsibles for the
* visibility-notify
*/
+ GdkScreen *screen;
+ GList *stack;
+ gboolean deactivate;
+
+ if (event->state == GDK_VISIBILITY_UNOBSCURED)
+ return FALSE;
+
+ screen = gtk_widget_get_screen (widget);
+
+ deactivate = FALSE;
+
+ /* Inspect windows above us */
+ stack = gdk_screen_get_window_stack (screen);
- return TRUE;
+ if (stack != NULL)
+ {
+ GList *iter;
+
+ iter = g_list_last (stack);
+
+ while (iter)
+ {
+ GdkWindow *win = iter->data;
+ GdkWindowTypeHint type;
+
+ if (win == widget->window)
+ break;
+
+ gdk_error_trap_push ();
+
+ type = gdk_window_get_type_hint (win);
+
+ if (!gdk_error_trap_pop () &&
+ /*type != GDK_WINDOW_TYPE_HINT_MESSAGE && */
+ type != GDK_WINDOW_TYPE_HINT_MENU)
+ {
+ /* A non-message and non-menu window above us; close. */
+ deactivate = TRUE;
+ break;
+ }
+
+ iter = iter->prev;
+ }
+
+ g_list_foreach (stack, (GFunc) g_object_unref, NULL);
+ g_list_free (stack);
+ }
+
+ if (deactivate)
+ {
+ hildon_desktop_popup_window_popdown (popup);
+ return TRUE;
+ }
+
+ return FALSE;
}
+static gboolean
+hildon_desktop_popup_window_button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ HildonDesktopPopupWindow *popup = HILDON_DESKTOP_POPUP_WINDOW (widget);
+ gboolean in_panes_area = FALSE,
+ in_window_area = FALSE;
+ gint x,y,w,h,i;
+
+ if (!event)
+ return FALSE;
+
+ gtk_widget_get_pointer (widget, &x, &y);
+
+ w = widget->allocation.width;
+ h = widget->allocation.height;
+
+ /* Pointer on window popup area */
+ if ((x >= 0) && (x <= w) && (y >= 0) && (y <= h))
+ in_window_area = TRUE;
+ else
+ {
+ for (i=0; i < popup->priv->n_extra_panes; i++)
+ {
+ w = popup->priv->extra_panes[i]->allocation.width;
+ h = popup->priv->extra_panes[i]->allocation.height;
+
+ gtk_widget_get_pointer (popup->priv->extra_panes[i], &x, &y);
+
+ /* Pointer on button area */
+ if ((x >= 0) && (x <= w) && (y >= 0) && (y <= h))
+ in_panes_area = TRUE;
+
+ break;
+ }
+ }
+
+ /* Event outside of popup or in button area, close in clean way */
+ if (!in_panes_area || in_window_area)
+ hildon_desktop_popup_window_popdown (popup);
+
+ return TRUE;
+}
+
static void
+hildon_desktop_popup_window_calculate_position (HildonDesktopPopupWindow *popup)
+{
+ gint x=0,y=0,i;
+ GtkRequisition req;
+
+ gtk_widget_size_request (GTK_WIDGET (popup), &req);
+
+ if (popup->priv->position_func)
+ {
+ (* popup->priv->position_func) (popup, &x, &y, popup->priv->position_func_data);
+ }
+
+ gtk_window_move (GTK_WINDOW (popup), x, y);
+
+ if (popup->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (popup->priv->direction == HD_POPUP_WINDOW_DIRECTION_RIGHT_BOTTOM)
+ for (i=0; i < popup->priv->n_extra_panes; i++)
+ gtk_window_move (GTK_WINDOW (popup->priv->extra_panes[i]),
+ req.width*(i+1) + x,
+ y);
+ else
+ if (popup->priv->direction == HD_POPUP_WINDOW_DIRECTION_LEFT_TOP)
+ for (i=0; i < popup->priv->n_extra_panes; i++)
+ gtk_window_move (GTK_WINDOW (popup->priv->extra_panes[i]),
+ req.width*(i+1) - x,
+ y);
+ }
+ else
+ if (popup->priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ if (popup->priv->direction == HD_POPUP_WINDOW_DIRECTION_RIGHT_BOTTOM)
+ for (i=0; i < popup->priv->n_extra_panes; i++)
+ gtk_window_move (GTK_WINDOW (popup->priv->extra_panes[i]),
+ x,
+ req.height*(i+1) + y);
+ else
+ if (popup->priv->direction == HD_POPUP_WINDOW_DIRECTION_LEFT_TOP)
+ for (i=0; i < popup->priv->n_extra_panes; i++)
+ gtk_window_move (GTK_WINDOW (popup->priv->extra_panes[i]),
+ x,
+ req.height*(i+1) - y);
+ }
+}
+
+static void
hildon_desktop_popup_window_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -397,10 +545,69 @@
}
}
+static GdkWindow *
+popup_window_grab_transfer_window_get (HildonDesktopPopupWindow *popup)
+{
+ GdkWindow *window =
+ g_object_get_data (G_OBJECT (popup),
+ "popup-window-transfer-window");
+
+ if (!window)
+ {
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+
+ attributes.x = -100;
+ attributes.y = -100;
+ attributes.width = 10;
+ attributes.height = 10;
+ attributes.window_type = GDK_WINDOW_TEMP;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.override_redirect = TRUE;
+ attributes.event_mask = 0;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
+
+ window = gdk_window_new (gtk_widget_get_root_window (GTK_WIDGET (popup)),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (window, popup);
+
+ gdk_window_show (window);
+
+ g_object_set_data (G_OBJECT (popup), "popup-window-transfer-window", window);
+ }
+
+ return window;
+}
+
+static gboolean
+popup_grab_on_window (GdkWindow *window,
+ guint32 activate_time,
+ gboolean grab_keyboard)
+{
+ if ((gdk_pointer_grab (window, TRUE,
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL, NULL, activate_time) == 0))
+ {
+ if (!grab_keyboard || gdk_keyboard_grab (window, TRUE, activate_time) == 0)
+ return TRUE;
+ else
+ {
+ gdk_display_pointer_ungrab
+ (gdk_drawable_get_display (window), activate_time);
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
GtkWidget *
-hildon_desktop_popup_window (guint n_panes,
- GtkOrientation orientation,
- HildonDesktopPopupWindowDirection direction)
+hildon_desktop_popup_window_new (guint n_panes,
+ GtkOrientation orientation,
+ HildonDesktopPopupWindowDirection direction)
{
return GTK_WIDGET (g_object_new (HILDON_DESKTOP_TYPE_POPUP_WINDOW,
"n-panes",n_panes,
@@ -425,8 +632,53 @@
void
hildon_desktop_popup_window_popup (HildonDesktopPopupWindow *popup,
- GtkMenuPositionFunc func)
+ HDPopupWindowPositionFunc func,
+ gpointer func_data,
+ guint32 activate_time)
{
+ GdkWindow *transfer_window;
+ GtkWidget *parent_toplevel;
+
+ g_assert (HILDON_DESKTOP_IS_POPUP_WINDOW (popup));
+
+ popup->priv->position_func = func;
+ popup->priv->position_func_data = func_data;
+ transfer_window = popup_window_grab_transfer_window_get (popup);
+ if (popup_grab_on_window (transfer_window, activate_time, TRUE))
+ popup->priv->have_xgrab = TRUE;
+
+ if (popup->priv->attached_widget)
+ {
+ parent_toplevel = gtk_widget_get_toplevel (popup->priv->attached_widget);
+
+ if (parent_toplevel && GTK_IS_WINDOW (parent_toplevel))
+ {
+ register gint i;
+ gtk_window_set_transient_for (GTK_WINDOW (popup),
+ GTK_WINDOW (parent_toplevel));
+
+ for (i=0; i < popup->priv->n_extra_panes; i++)
+ gtk_window_set_transient_for (GTK_WINDOW (popup->priv->extra_panes[i]),
+ GTK_WINDOW (parent_toplevel));
+ }
+ }
+
+ hildon_desktop_popup_window_calculate_position (popup);
+
+ gtk_widget_show (GTK_WIDGET (popup));
+
+ popup_grab_on_window (GTK_WIDGET (popup)->window, activate_time, TRUE); /* Should always succeed */
+
+ gtk_grab_add (GTK_WIDGET (popup));
}
+
+void
+hildon_desktop_popup_window_popdown (HildonDesktopPopupWindow *popup)
+{
+ gtk_widget_hide (GTK_WIDGET (popup));
+
+ gtk_grab_remove (GTK_WIDGET (popup));
+}
+
Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h 2007-04-20 14:46:29 UTC (rev 11186)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h 2007-04-20 15:08:48 UTC (rev 11187)
@@ -27,15 +27,19 @@
#define __HILDON_DESKTOP_POPUP_WINDOW_H__
#include <gtk/gtkwindow.h>
+#include <gdk/gdk.h>
-#include <gtk/gtkmenu.h> /*Only for GtkMenuPositionFunc*/
-
G_BEGIN_DECLS
typedef struct _HildonDesktopPopupWindow HildonDesktopPopupWindow;
typedef struct _HildonDesktopPopupWindowClass HildonDesktopPopupWindowClass;
typedef struct _HildonDesktopPopupWindowPrivate HildonDesktopPopupWindowPrivate;
+typedef void (*HDPopupWindowPositionFunc) (HildonDesktopPopupWindow *window,
+ gint *x,
+ gint *y,
+ gpointer user_data);
+
typedef enum
{
HD_POPUP_WINDOW_DIRECTION_LEFT_TOP,
@@ -58,24 +62,29 @@
struct _HildonDesktopPopupWindowClass
{
+ GtkWindowClass parent_class;
/* */
-}
+};
GType
hildon_desktop_popup_window_get_type (void);
GtkWidget *
-hildon_desktop_popup_window (guint n_panes,
- GtkOrientation orientation,
- HildonDesktopPopupWindowDirection direction);
+hildon_desktop_popup_window_new (guint n_panes,
+ GtkOrientation orientation,
+ HildonDesktopPopupWindowDirection direction);
GtkWidget *
hildon_desktop_popup_window_get_pane (HildonDesktopPopupWindow *popup, gint pane);
void
hildon_desktop_popup_window_popup (HildonDesktopPopupWindow *popup,
- GtkMenuPositionFunc func);
+ HDPopupWindowPositionFunc func,
+ gpointer func_data,
+ guint32 activate_time);
+void
+hildon_desktop_popup_window_popdown (HildonDesktopPopupWindow *popup);
G_BEGIN_DECLS
- Previous message: [maemo-commits] r11186 - in projects/haf/trunk/hail: . docs
- Next message: [maemo-commits] r11188 - in projects/haf/trunk/hildon-desktop: . debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
