Eitan Isaacson has proposed merging lp:~eeejay/notify-osd/text_iface into
lp:notify-osd.
Requested reviews:
Notify OSD Developers (notify-osd-developers)
This branch adds a text interface and relevant AT-SPI events for dynamic bubble
messages and titles.
--
https://code.launchpad.net/~eeejay/notify-osd/text_iface/+merge/5919
Your team Notify OSD Developers is subscribed to branch lp:notify-osd.
=== modified file 'src/bubble-window-accessible.c'
--- src/bubble-window-accessible.c 2009-02-27 20:00:53 +0000
+++ src/bubble-window-accessible.c 2009-04-27 08:45:53 +0000
@@ -37,6 +37,7 @@
static void bubble_window_real_initialize (AtkObject* obj,
gpointer data);
static void atk_value_interface_init (AtkValueIface* iface);
+static void atk_text_interface_init (AtkTextIface* iface);
static void bubble_window_get_current_value (AtkValue* obj,
GValue* value);
static void bubble_window_get_maximum_value (AtkValue* obj,
@@ -46,6 +47,19 @@
static void bubble_value_changed_event (Bubble* bubble,
gint value,
AtkObject *obj);
+static void bubble_message_body_deleted_event (Bubble* bubble,
+ const gchar* text,
+ AtkObject* obj);
+static void bubble_message_body_inserted_event (Bubble* bubble,
+ const gchar* text,
+ AtkObject* obj);
+
+static gchar* bubble_window_get_text (AtkText *obj,
+ gint start_offset,
+ gint end_offset);
+static gint bubble_window_get_character_count (AtkText *obj);
+static gunichar bubble_window_get_character_at_offset (AtkText *obj,
+ gint offset);
static void* bubble_window_accessible_parent_class;
@@ -76,6 +90,13 @@
(GInterfaceFinalizeFunc) NULL,
NULL
};
+
+ const GInterfaceInfo atk_text_info =
+ {
+ (GInterfaceInitFunc) atk_text_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
/*
* Figure out the size of the class and instance
@@ -100,6 +121,8 @@
"BubbleWindowAccessible", &tinfo, 0);
g_type_add_interface_static (type, ATK_TYPE_VALUE, &atk_value_info);
+
+ g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info);
}
return type;
@@ -116,6 +139,17 @@
}
static void
+atk_text_interface_init (AtkTextIface* iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->get_text = bubble_window_get_text;
+ iface->get_character_count = bubble_window_get_character_count;
+ iface->get_character_at_offset = bubble_window_get_character_at_offset;
+
+}
+
+static void
bubble_window_accessible_init (BubbleWindowAccessible *object)
{
/* TODO: Add initialization code here */
@@ -160,6 +194,16 @@
G_CALLBACK (bubble_value_changed_event),
obj);
+ g_signal_connect (bubble,
+ "message-body-deleted",
+ G_CALLBACK (bubble_message_body_deleted_event),
+ obj);
+
+ g_signal_connect (bubble,
+ "message-body-inserted",
+ G_CALLBACK (bubble_message_body_inserted_event),
+ obj);
+
}
AtkObject*
@@ -286,3 +330,108 @@
{
g_object_notify (G_OBJECT (obj), "accessible-value");
}
+
+static void
+bubble_message_body_deleted_event (Bubble* bubble,
+ const gchar* text,
+ AtkObject* obj)
+{
+ /* Not getting very fancy here, delete is always complete */
+ g_signal_emit_by_name (
+ obj, "text_changed::delete", 0, g_utf8_strlen (text, -1));
+}
+
+static void
+bubble_message_body_inserted_event (Bubble* bubble,
+ const gchar* text,
+ AtkObject* obj)
+{
+ const gchar* message_body;
+
+ message_body = bubble_get_message_body (bubble);
+
+ g_signal_emit_by_name (
+ obj, "text_changed::insert",
+ g_utf8_strlen (message_body, -1) - g_utf8_strlen (text, -1),
+ g_utf8_strlen (message_body, -1));
+}
+
+static gchar*
+bubble_window_get_text (AtkText *obj,
+ gint start_offset,
+ gint end_offset)
+{
+ GtkAccessible* accessible;
+ Bubble* bubble;
+ const gchar* body_text;
+ gsize char_length;
+ glong body_strlen;
+
+ g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), g_strdup(""));
+
+ accessible = GTK_ACCESSIBLE (obj);
+
+ g_return_val_if_fail (accessible->widget == NULL, g_strdup(""));
+
+ bubble = g_object_get_data (G_OBJECT(accessible->widget), "bubble");
+
+ if (end_offset <= start_offset)
+ return g_strdup("");
+
+ body_text = bubble_get_message_body (bubble);
+
+ body_strlen = g_utf8_strlen(body_text, -1);
+
+ if (start_offset > body_strlen)
+ start_offset = body_strlen;
+
+ if (end_offset > body_strlen || end_offset == -1)
+ end_offset = body_strlen;
+
+
+ char_length = g_utf8_offset_to_pointer (body_text, end_offset) -
+ g_utf8_offset_to_pointer (body_text, start_offset);
+
+ return g_strndup (g_utf8_offset_to_pointer(body_text, start_offset),
+ char_length);
+}
+
+static gint
+bubble_window_get_character_count (AtkText *obj)
+{
+ GtkAccessible* accessible;
+ Bubble* bubble;
+
+ g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), 0);
+
+ accessible = GTK_ACCESSIBLE (obj);
+
+ if (accessible->widget == NULL)
+ return 0;
+
+ bubble = g_object_get_data (G_OBJECT(accessible->widget), "bubble");
+
+ return g_utf8_strlen(bubble_get_message_body (bubble), -1);
+}
+
+static gunichar
+bubble_window_get_character_at_offset (AtkText *obj,
+ gint offset)
+{
+ GtkAccessible* accessible;
+ Bubble* bubble;
+ const gchar* body_text;
+
+ g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), 0);
+
+ accessible = GTK_ACCESSIBLE (obj);
+
+ if (accessible->widget == NULL)
+ return 0;
+
+ bubble = g_object_get_data (G_OBJECT(accessible->widget), "bubble");
+
+ body_text = bubble_get_message_body (bubble);
+
+ return g_utf8_get_char (g_utf8_offset_to_pointer (body_text, offset));
+}
=== modified file 'src/bubble.c'
--- src/bubble.c 2009-04-16 14:13:47 +0000
+++ src/bubble.c 2009-04-27 08:54:00 +0000
@@ -94,6 +94,8 @@
{
TIMED_OUT,
VALUE_CHANGED,
+ MESSAGE_BODY_DELETED,
+ MESSAGE_BODY_INSERTED,
LAST_SIGNAL
};
@@ -1903,6 +1905,30 @@
G_TYPE_NONE,
1,
G_TYPE_INT);
+
+ g_bubble_signals[MESSAGE_BODY_DELETED] = g_signal_new (
+ "message-body-deleted",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (BubbleClass, message_body_deleted),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ g_bubble_signals[MESSAGE_BODY_INSERTED] = g_signal_new (
+ "message-body-inserted",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (BubbleClass, message_body_inserted),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
}
/*-- public API --------------------------------------------------------------*/
@@ -2066,6 +2092,10 @@
g_string_free (priv->title, TRUE);
priv->title = g_string_new (title);
+
+ g_object_notify (
+ G_OBJECT (gtk_widget_get_accessible (GET_PRIVATE(self)->widget)),
+ "accessible-name");
}
const gchar*
@@ -2089,13 +2119,20 @@
priv = GET_PRIVATE (self);
- if (priv->message_body->len != 0)
+ if (priv->message_body->len != 0) {
+ g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_DELETED],
+ 0, priv->message_body->str);
g_string_free (priv->message_body, TRUE);
-
+ }
/* filter out any HTML/markup if possible */
text = filter_text (body);
priv->message_body = g_string_new (text);
+
+ g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text);
+ g_object_notify (G_OBJECT (gtk_widget_get_accessible (priv->widget)),
+ "accessible-description");
+
g_free (text);
}
@@ -3387,6 +3424,12 @@
/* append text to current message-body */
g_string_append (GET_PRIVATE (self)->message_body, text);
+ g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text);
+
+ g_object_notify (
+ G_OBJECT (gtk_widget_get_accessible (GET_PRIVATE(self)->widget)),
+ "accessible-description");
+
g_free ((gpointer) text);
}
=== modified file 'src/bubble.h'
--- src/bubble.h 2009-04-09 10:44:07 +0000
+++ src/bubble.h 2009-04-23 15:22:58 +0000
@@ -76,6 +76,8 @@
/*< signals >*/
void (*timed_out) (Bubble* bubble);
void (*value_changed) (Bubble* bubble);
+ void (*message_body_deleted) (Bubble* bubble);
+ void (*message_body_inserted) (Bubble* bubble);
};
GType bubble_get_type (void);
_______________________________________________
Mailing list: https://launchpad.net/~dx-team
Post to : [email protected]
Unsubscribe : https://launchpad.net/~dx-team
More help : https://help.launchpad.net/ListHelp