rpms/notification-daemon/devel notification-daemon-positioning.patch, NONE, 1.1 notification-daemon-svn3009-distfix.patch, NONE, 1.1 notification-daemon.spec, 1.20, 1.21
Colin Walters (walters)
fedora-extras-commits at redhat.com
Tue Jun 10 16:17:47 UTC 2008
- Previous message (by thread): [pkgdb] tcputils (Fedora EPEL, 4) updated by kevin
- Next message (by thread): rpms/xmoto-edit/devel dead.package, NONE, 1.1 sources, 1.4, NONE xmoto-edit-0.2.4-Editor-flag.patch, 1.1, NONE xmoto-edit-man.patch, 1.1, NONE xmoto-edit.desktop, 1.1, NONE xmoto-edit.png, 1.1, NONE xmoto-edit.spec, 1.9, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: walters
Update of /cvs/pkgs/rpms/notification-daemon/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv2861
Modified Files:
notification-daemon.spec
Added Files:
notification-daemon-positioning.patch
notification-daemon-svn3009-distfix.patch
Log Message:
* Tue Jun 10 2008 Colin Walters <walters at redhat.com> -0.3.7.90-0.svn3009
- Update to SVN snapshot 3009 so we can apply:
- Add positioning patch
- Add patch to fix the dist
- Drop upstreamed summary patch
notification-daemon-positioning.patch:
--- NEW FILE notification-daemon-positioning.patch ---
Index: src/daemon/daemon.c
===================================================================
--- src/daemon/daemon.c (revision 3009)
+++ src/daemon/daemon.c (working copy)
@@ -81,15 +81,19 @@
GTimeVal paused_diff;
gboolean has_timeout;
gboolean paused;
+ gint cached_x;
+ gint cached_y;
guint id;
GtkWindow *nw;
-
+ Window srcwindow_xid;
} NotifyTimeout;
struct _NotifyDaemonPrivate
{
guint next_id;
guint timeout_source;
+ GHashTable *idle_reposition_notify_ids;
+ GHashTable *monitored_window_hash;
GHashTable *notification_hash;
gboolean url_clicked_lock;
NotifyStack **stacks;
@@ -118,9 +122,14 @@
static void _close_notification(NotifyDaemon *daemon, guint id,
gboolean hide_notification,
NotifydClosedReason reason);
+static GdkFilterReturn _notify_x11_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data);
static void _emit_closed_signal(GtkWindow *nw, NotifydClosedReason reason);
static void _action_invoked_cb(GtkWindow *nw, const char *key);
static NotifyStackLocation get_stack_location_from_string(const char *slocation);
+static void sync_notification_position(NotifyDaemon *daemon, NotifyTimeout *nt);
+static void monitor_notification_source_windows(NotifyDaemon *daemon, NotifyTimeout *nt, Window source);
G_DEFINE_TYPE(NotifyDaemon, notify_daemon, G_TYPE_OBJECT);
@@ -167,6 +176,10 @@
daemon->priv->stacks_size = gdk_screen_get_n_monitors(screen);
daemon->priv->stacks = g_new0(NotifyStack *, daemon->priv->stacks_size);
+ daemon->priv->idle_reposition_notify_ids = g_hash_table_new (NULL, NULL);
+ daemon->priv->monitored_window_hash = g_hash_table_new (NULL, NULL);
+ gdk_window_add_filter (NULL, _notify_x11_filter, daemon);
+
for (i = 0; i < daemon->priv->stacks_size; i++)
{
daemon->priv->stacks[i] = notify_stack_new(daemon, screen,
@@ -184,6 +197,8 @@
NotifyDaemon *daemon = NOTIFY_DAEMON(object);
GObjectClass *parent_class = G_OBJECT_CLASS(notify_daemon_parent_class);
+ g_hash_table_destroy(daemon->priv->monitored_window_hash);
+ g_hash_table_destroy(daemon->priv->idle_reposition_notify_ids);
g_hash_table_destroy(daemon->priv->notification_hash);
g_free(daemon->priv);
@@ -295,7 +310,99 @@
NOTIFYD_CLOSED_EXPIRED);
}
+struct idle_reposition_data
+{
+ NotifyDaemon *daemon;
+ gint id;
+};
+
+static gboolean
+idle_reposition_notification(gpointer datap)
+{
+ struct idle_reposition_data *data=(struct idle_reposition_data*)datap;
+ NotifyDaemon *daemon = data->daemon;
+ NotifyTimeout *nt;
+ gint notify_id;
+
+ notify_id = data->id;
+
+ /* Look up the timeout, if it's completed we don't need to do anything */
+ nt = (NotifyTimeout *)g_hash_table_lookup(daemon->priv->notification_hash, ¬ify_id);
+ if (!nt)
+ goto out;
+
+ sync_notification_position(daemon, nt);
+
+ out:
+ g_hash_table_remove(daemon->priv->idle_reposition_notify_ids, GINT_TO_POINTER(notify_id));
+ g_object_unref(daemon);
+ g_free(data);
+ return FALSE;
+}
+
static void
+_queue_idle_reposition_notification(NotifyDaemon *daemon, gint notify_id)
+{
+ struct idle_reposition_data *data;
+ gpointer orig_key;
+ gpointer value;
+ guint idle_id;
+
+ /* Do we already have an idle update pending? */
+ if (g_hash_table_lookup_extended(daemon->priv->idle_reposition_notify_ids,
+ GINT_TO_POINTER (notify_id), &orig_key, &value))
+ return;
+
+ data = g_new0(struct idle_reposition_data, 1);
+ g_object_ref (daemon);
+ data->daemon = daemon;
+ data->id = notify_id;
+ /* We do this as a short timeout to avoid repositioning spam */
+ idle_id = g_timeout_add_full (G_PRIORITY_LOW, 50, idle_reposition_notification, data, NULL);
+ g_hash_table_insert (daemon->priv->idle_reposition_notify_ids,
+ GINT_TO_POINTER (notify_id), GUINT_TO_POINTER (idle_id));
+}
+
+static GdkFilterReturn
+_notify_x11_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ NotifyDaemon *daemon = NOTIFY_DAEMON (user_data);
+ XEvent *xev = (XEvent *)xevent;
+ gpointer orig_key;
+ gpointer value;
+ gint notify_id;
+ NotifyTimeout *nt;
+
+ if (xev->xany.type == DestroyNotify)
+ {
+ g_hash_table_remove(daemon->priv->monitored_window_hash, GUINT_TO_POINTER(xev->xany.window));
+ return GDK_FILTER_CONTINUE;
+ }
+
+ if (!g_hash_table_lookup_extended(daemon->priv->monitored_window_hash,
+ GUINT_TO_POINTER(xev->xany.window), &orig_key, &value))
+ return GDK_FILTER_CONTINUE;
+
+ notify_id = GPOINTER_TO_INT (value);
+ if (xev->xany.type == ConfigureNotify || xev->xany.type == MapNotify)
+ {
+ _queue_idle_reposition_notification(daemon, notify_id);
+ }
+ else if (xev->xany.type == ReparentNotify)
+ {
+ nt = (NotifyTimeout *)g_hash_table_lookup(daemon->priv->notification_hash, ¬ify_id);
+ if (!nt)
+ return GDK_FILTER_CONTINUE;
+ /* If the window got reparented, we need to start monitoring the new parents */
+ monitor_notification_source_windows(daemon, nt, nt->srcwindow_xid);
+ sync_notification_position(daemon, nt);
+ }
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
_mouse_entered_cb(GtkWindow *nw, GdkEventCrossing *event, NotifyDaemon *daemon)
{
NotifyTimeout *nt;
@@ -436,7 +543,7 @@
}
}
-static guint
+static NotifyTimeout *
_store_notification(NotifyDaemon *daemon, GtkWindow *nw, int timeout)
{
NotifyDaemonPrivate *priv = daemon->priv;
@@ -460,13 +567,15 @@
nt = g_new0(NotifyTimeout, 1);
nt->id = id;
nt->nw = nw;
+ nt->cached_x = -1;
+ nt->cached_y = -1;
_calculate_timeout(daemon, nt, timeout);
g_hash_table_insert(priv->notification_hash,
g_memdup(&id, sizeof(guint)), nt);
- return id;
+ return nt;
}
static gboolean
@@ -634,7 +743,7 @@
if (expected_len != tmp_array->len)
{
g_warning("_notify_daemon_process_icon_data expected image "
- "data to be of length %i but got a length of %i",
+ "data to be of length %" G_GSIZE_FORMAT " but got a length of %u",
expected_len, tmp_array->len);
return FALSE;
}
@@ -822,6 +931,101 @@
return FALSE;
}
+static Window
+get_window_parent (Display *display, Window window, Window *root)
+{
+ Window parent;
+ Window *children = NULL;
+ guint nchildren;
+ gboolean result;
+
+ gdk_error_trap_push ();
+ result = XQueryTree (display, window, root, &parent, &children, &nchildren);
+ if (gdk_error_trap_pop () || !result)
+ return None;
+
+ if (children)
+ XFree (children);
+ return parent;
+}
+
+/* Recurse over X Window and parents, up to root, and start watching them
+ * for position changes
+ */
+static void
+monitor_notification_source_windows(NotifyDaemon *daemon, NotifyTimeout *nt, Window source)
+{
+ Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+ Window root = None;
+ Window parent;
+
+ /* Store the window in the timeout */
+ g_assert(nt != NULL);
+ nt->srcwindow_xid = source;
+
+ parent = get_window_parent(display, source, &root);
+ while ((parent != None) && root != parent) {
+ XSelectInput(display, parent, StructureNotifyMask);
+ g_hash_table_insert(daemon->priv->monitored_window_hash,
+ GUINT_TO_POINTER(parent), GINT_TO_POINTER(nt->id));
+
+ parent = get_window_parent(display, parent, &root);
+ }
+}
+
+/* Use a source X Window ID to reposition a notification */
+static void
+sync_notification_position(NotifyDaemon *daemon, NotifyTimeout *nt)
+{
+ Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+ Window source = nt->srcwindow_xid;
+ GtkWindow *nw = nt->nw;
+ Status result;
+ Window root;
+ Window child;
+ int x, y;
+ unsigned int width, height;
+ unsigned int border_width, depth;
+
+
+ gdk_error_trap_push ();
+ /* Get the root for this window */
+ result = XGetGeometry (display, source,
+ &root, &x, &y, &width, &height, &border_width, &depth);
+ if (gdk_error_trap_pop () || !result)
+ {
+ return;
+ }
+ /* Now calculate the offset coordinates for the source window from the root */
+ gdk_error_trap_push ();
+ result = XTranslateCoordinates (display,
+ source,
+ root,
+ 0, 0, &x, &y,
+ &child);
+ if (gdk_error_trap_pop () || !result)
+ {
+ return;
+ }
+
+ x += (width/2);
+ y += (height/2);
+
+ if (x == nt->cached_x && y == nt->cached_y)
+ return;
+ nt->cached_x = x;
+ nt->cached_y = y;
+
+ fprintf(stderr, "repositioning at %i %i\n", x, y);
+ theme_set_notification_arrow(nw, TRUE, x, y);
+ theme_move_notification(nw, x, y);
+ /* We need to do a full draw as the default theme recalculates
+ * its position in the draw handler and moves the window (which seems fairly
+ * broken), so just calling set_arrow/move isn't enough to cause its position to
+ * be calculated. */
+ gtk_widget_queue_draw(GTK_WIDGET(nw));
+}
+
GQuark
notify_daemon_error_quark(void)
{
@@ -852,6 +1056,7 @@
gboolean new_notification = FALSE;
gint x = 0;
gint y = 0;
+ Window window_xid = None;
guint return_id;
gchar *sender;
gchar *sound_file = NULL;
@@ -897,8 +1102,13 @@
*XXX This needs to handle file URIs and all that.
*/
+
+ if ((data = (GValue *)g_hash_table_lookup(hints, "window-xid")) != NULL)
+ {
+ window_xid = (Window) g_value_get_uint(data);
+ }
/* deal with x, and y hints */
- if ((data = (GValue *)g_hash_table_lookup(hints, "x")) != NULL)
+ else if ((data = (GValue *)g_hash_table_lookup(hints, "x")) != NULL)
{
x = g_value_get_int(data);
@@ -1044,8 +1254,15 @@
}
}
- if (use_pos_data)
+
+ if (window_xid != None)
{
+ /* Do nothing here if we were passed an XID; we'll call
+ * sync_notification_position later.
+ */
+ }
+ else if (use_pos_data)
+ {
/*
* Typically, the theme engine will set its own position based on
* the arrow X, Y hints. However, in case, move the notification to
@@ -1070,6 +1287,24 @@
notify_stack_add_window(priv->stacks[monitor], nw, new_notification);
}
+ if (id == 0)
+ {
+ nt = _store_notification(daemon, nw, timeout);
+ return_id = nt->id;
+ }
+ else
+ return_id = id;
+
+ /* If we have a source Window XID, start monitoring the tree
+ * for changes, and reposition the window based on the source
+ * window. We need to do this after return_id is calculated.
+ */
+ if (window_xid != None)
+ {
+ monitor_notification_source_windows(daemon, nt, window_xid);
+ sync_notification_position(daemon, nt);
+ }
+
if (!screensaver_active(GTK_WIDGET(nw)) &&
!fullscreen_window_exists(GTK_WIDGET(nw)))
{
@@ -1080,8 +1315,6 @@
g_free(sound_file);
- return_id = (id == 0 ? _store_notification(daemon, nw, timeout) : id);
-
#if CHECK_DBUS_VERSION(0, 60)
sender = dbus_g_method_get_sender(context);
#else
Index: src/themes/standard/theme.c
===================================================================
--- src/themes/standard/theme.c (revision 3009)
+++ src/themes/standard/theme.c (working copy)
@@ -214,6 +214,7 @@
int width;
int height;
int y;
+ int target_x, target_y;
int norm_point_x;
int norm_point_y;
GtkArrowType arrow_type;
@@ -259,14 +260,10 @@
}
else
{
- if (norm_point_x - arrow_side2_width + width >=
- monitor_geometry.width)
+ int right_x = norm_point_x - arrow_side1_width + width;
+ if (right_x >= monitor_geometry.width)
{
- arrow_offset =
- width - arrow_side1_width - arrow_side2_width -
- monitor_geometry.width -
- MAX(norm_point_x + arrow_side1_width,
- monitor_geometry.width - DEFAULT_ARROW_OFFSET);
+ arrow_offset = right_x - monitor_geometry.width;
}
else
{
@@ -384,10 +381,9 @@
g_assert(i == windata->num_border_points);
g_assert(windata->point_x - arrow_offset - arrow_side1_width >= 0);
#endif
- gtk_window_move(GTK_WINDOW(windata->win),
- windata->point_x - arrow_offset -
- arrow_side1_width,
- y);
+ target_x = windata->point_x - arrow_offset - arrow_side1_width;
+ target_y = y;
+ gtk_window_move(GTK_WINDOW(windata->win), target_x, target_y);
break;
notification-daemon-svn3009-distfix.patch:
--- NEW FILE notification-daemon-svn3009-distfix.patch ---
Index: src/capplet/Makefile.am
===================================================================
--- src/capplet/Makefile.am (revision 3009)
+++ src/capplet/Makefile.am (working copy)
@@ -20,4 +20,4 @@
-DNOTIFICATION_GLADEDIR=\"$(datadir)/notification-daemon\"
CLEANFILES = $(desktop_DATA)
-EXTRA_DIST = $(glade_DATA) $(pixmap_DATA)
+EXTRA_DIST = $(glade_DATA) $(pixmap_DATA) $(desktop_in_files)
Index: notification-daemon.spec
===================================================================
RCS file: /cvs/pkgs/rpms/notification-daemon/devel/notification-daemon.spec,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- notification-daemon.spec 7 Apr 2008 03:33:57 -0000 1.20
+++ notification-daemon.spec 10 Jun 2008 16:17:01 -0000 1.21
@@ -6,8 +6,8 @@
Summary: Notification Daemon
Name: notification-daemon
-Version: 0.3.7
-Release: 9%{?dist}
+Version: 0.3.7.90
+Release: 0.svn3009%{?dist}
URL: http://www.galago-project.org/specs/notification/
License: GPLv2+
Group: System Environment/Libraries
@@ -31,10 +31,11 @@
Obsoletes: notify-daemon
-Source0: http://www.galago-project.org/files/releases/source/notification-daemon/%{name}-%{version}.tar.bz2
+Source0: http://www.galago-project.org/files/releases/source/notification-daemon/%{name}-%{version}.tar.gz
Patch0: notification-daemon-0.3.5-remove-libsexy.patch
-Patch1: notification-daemon-0.3.7-summary-markup.patch
Patch2: notification-daemon-clipping.patch
+Patch3: notification-daemon-svn3009-distfix.patch
+Patch4: notification-daemon-positioning.patch
%description
notification-daemon is the server implementation of the freedesktop.org desktop
@@ -43,8 +44,9 @@
%prep
%setup -q
%patch0 -p1 -b .remove-libsexy
-%patch1 -p1 -b .summary-markup
%patch2 -p1 -b .clipping
+%patch3 -p0 -b .svn3009-distfix
+%patch4 -p0 -b .positioning
%build
autoreconf
@@ -97,6 +99,12 @@
%config %{_sysconfdir}/gconf/schemas/notification-daemon.schemas
%changelog
+* Tue Jun 10 2008 Colin Walters <walters at redhat.com> -0.3.7.90-0.svn3009
+- Update to SVN snapshot 3009 so we can apply:
+- Add positioning patch
+- Add patch to fix the dist
+- Drop upstreamed summary patch
+
* Sun Apr 6 2008 Jon McCann <jmccann at redhat.com> - 0.3.7-9
- Don't clip text in message bubbles (#441099)
- Previous message (by thread): [pkgdb] tcputils (Fedora EPEL, 4) updated by kevin
- Next message (by thread): rpms/xmoto-edit/devel dead.package, NONE, 1.1 sources, 1.4, NONE xmoto-edit-0.2.4-Editor-flag.patch, 1.1, NONE xmoto-edit-man.patch, 1.1, NONE xmoto-edit.desktop, 1.1, NONE xmoto-edit.png, 1.1, NONE xmoto-edit.spec, 1.9, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list