/* GtkTable already calls gtk_table_resize() if necessary */
gtk_table_attach_defaults (priv->table, GTK_WIDGET (item), col, col + 1, row, row + 1);
- /* Close the menu when the button is pressed */
+ /* Close the menu when the button is clicked */
g_signal_connect_swapped (item, "clicked", G_CALLBACK (gtk_widget_hide), menu);
gtk_widget_show (GTK_WIDGET (item));
gtk_box_pack_start (GTK_BOX (group), GTK_WIDGET (filter), TRUE, TRUE, 0);
gtk_size_group_add_widget (priv->sizegroup, GTK_WIDGET (filter));
- /* Close the menu when the button is pressed */
+ /* Close the menu when the button is clicked */
g_signal_connect_swapped (filter, "clicked", G_CALLBACK (gtk_widget_hide), menu);
gtk_widget_show (GTK_WIDGET (filter));
}
static gboolean
-hildon_app_menu_button_press (GtkWidget *widget,
+hildon_app_menu_button_release (GtkWidget *widget,
GdkEventButton *event)
{
int x, y;
+ gboolean released_outside;
HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(widget);
- gdk_window_get_position(widget->window, &x, &y);
- if (event->window != priv->transfer_window ||
- event->x < x || event->x > x + widget->allocation.width ||
- event->y < y || event->y > y + widget->allocation.height) {
+
+ gdk_window_get_position (widget->window, &x, &y);
+
+ /* Whether the button has been released outside the widget */
+ released_outside = (event->window != priv->transfer_window ||
+ event->x < x || event->x > x + widget->allocation.width ||
+ event->y < y || event->y > y + widget->allocation.height);
+
+ if (released_outside) {
gtk_widget_hide (widget);
- return TRUE;
- } else if (GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_press_event) {
- return GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_press_event (widget, event);
+ }
+
+ if (GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_release_event) {
+ return GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_release_event (widget, event);
} else {
return FALSE;
}
widget_class->map = hildon_app_menu_map;
widget_class->unmap = hildon_app_menu_unmap;
widget_class->realize = hildon_app_menu_realize;
- widget_class->button_press_event = hildon_app_menu_button_press;
+ widget_class->button_release_event = hildon_app_menu_button_release;
g_type_class_add_private (klass, sizeof (HildonAppMenuPrivate));
static void
hildon_note_finalize (GObject *obj_self);
+static gboolean
+hildon_note_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+
+static void
+hildon_note_map (GtkWidget *widget);
+
+static void
+hildon_note_unmap (GtkWidget *widget);
+
static void
hildon_note_realize (GtkWidget *widget);
static GtkDialogClass* parent_class;
+static GdkWindow *
+grab_transfer_window_get (GtkWidget *widget)
+{
+ GdkWindow *window;
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+
+ attributes.x = 0;
+ attributes.y = 0;
+ 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 (widget),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (window, widget);
+
+ gdk_window_show (window);
+
+ return window;
+}
+
static void
hildon_note_set_property (GObject *object,
guint prop_id,
object_class->finalize = hildon_note_finalize;
object_class->set_property = hildon_note_set_property;
object_class->get_property = hildon_note_get_property;
+ widget_class->button_release_event = hildon_note_button_release;
+ widget_class->map = hildon_note_map;
+ widget_class->unmap = hildon_note_unmap;
widget_class->realize = hildon_note_realize;
g_object_class_install_property (object_class,
gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
priv->icon = gtk_image_new ();
+ priv->close_if_pressed_outside = FALSE;
+ priv->transfer_window = NULL;
/* Acquire real references to our internal children, since
they are not nessecarily packed into container in each
G_OBJECT_CLASS (parent_class)->finalize (obj_self);
}
+
+static gboolean
+hildon_note_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ int x, y;
+ gboolean released_outside;
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
+
+ gdk_window_get_position (widget->window, &x, &y);
+
+ /* Whether the button has been released outside the widget */
+ released_outside = (event->window != priv->transfer_window ||
+ event->x < x || event->x > x + widget->allocation.width ||
+ event->y < y || event->y > y + widget->allocation.height);
+
+ if (released_outside && priv->close_if_pressed_outside) {
+ gtk_dialog_response (GTK_DIALOG (widget), GTK_RESPONSE_CANCEL);
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->button_release_event) {
+ return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
+ } else {
+ return FALSE;
+ }
+}
+
+static void
+hildon_note_map (GtkWidget *widget)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
+ g_assert (priv);
+
+ /* Map the window */
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+ if (priv->transfer_window == NULL && priv->close_if_pressed_outside) {
+ priv->transfer_window = grab_transfer_window_get (widget);
+ gdk_pointer_grab (
+ priv->transfer_window, TRUE,
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME);
+ gdk_keyboard_grab (priv->transfer_window, TRUE, GDK_CURRENT_TIME);
+ gtk_grab_add (widget);
+ }
+}
+
+static void
+hildon_note_unmap (GtkWidget *widget)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
+ g_assert (priv);
+
+ if (priv->transfer_window != NULL) {
+ /* Remove the grab */
+ gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
+ GDK_CURRENT_TIME);
+ gtk_grab_remove (widget);
+
+ /* Destroy the transfer window */
+ gdk_window_destroy (priv->transfer_window);
+ priv->transfer_window = NULL;
+ }
+}
+
static void
hildon_note_realize (GtkWidget *widget)
{
if (priv->sound_signal_handler == 0)
priv->sound_signal_handler = g_signal_connect_after(widget,
"expose-event", G_CALLBACK (sound_handling), NULL);
+
+ /* We use special hint to turn the note into information notification. */
+ gdk_window_set_type_hint (widget->window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
}
/* Helper function for removing a widget from it's container.
priv->cancelButton = NULL;
}
+ /* By default the note won't be closed when pressing outside */
+ priv->close_if_pressed_outside = FALSE;
+
/* Add needed buttons and images for each note type */
switch (priv->note_n)
{
case HILDON_NOTE_TYPE_INFORMATION_THEME:
case HILDON_NOTE_TYPE_INFORMATION:
- /* Add clickable OK button (cancel really,
- but doesn't matter since this is info) */
- priv->cancelButton = gtk_dialog_add_button (dialog,
- _("ecdg_bd_information_note_ok"), GTK_RESPONSE_CANCEL);
+ priv->close_if_pressed_outside = TRUE;
gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon),
HILDON_NOTE_INFORMATION_ICON,
HILDON_ICON_SIZE_BIG_NOTE);