summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac9
-rw-r--r--openbox/Makefile.am6
-rw-r--r--openbox/event.c8
-rw-r--r--openbox/openbox.c7
-rw-r--r--openbox/openbox.h11
-rw-r--r--openbox/screen.c89
6 files changed, 123 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 16f54e28..c8174de3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,10 +51,17 @@ PKG_CHECK_MODULES([GMODULE], [gmodule-2.0])
AC_SUBST(GMODULE_CFLAGS)
AC_SUBST(GMODULE_LIBS)
-PKG_CHECK_MODULES(XFT, xft)
+PKG_CHECK_MODULES(XFT, [xft])
AC_SUBST(XFT_CFLAGS)
AC_SUBST(XFT_LIBS)
+PKG_CHECK_MODULES(LIBSN, [libstartup-notification-1.0])
+AC_SUBST(LIBSN_CFLAGS)
+AC_SUBST(LIBSN_LIBS)
+if test "$LIBSN_LIBS"; then
+ AC_DEFINE(USE_LIBSN)
+fi
+
# Check for X11 extensions
X11_EXT_XKB
X11_EXT_XRANDR
diff --git a/openbox/Makefile.am b/openbox/Makefile.am
index 795b26a6..ac277c01 100644
--- a/openbox/Makefile.am
+++ b/openbox/Makefile.am
@@ -6,7 +6,7 @@ binary=openbox3
url=http://icculus.org/openbox
CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \
- @CPPFLAGS@ \
+ $(LIBSN_CFLAGS) @CPPFLAGS@ \
-DLOCALEDIR=\"$(localedir)\" \
-DRCDIR=\"$(rcdir)\" \
-DPLUGINDIR=\"$(plugindir)\" \
@@ -15,8 +15,8 @@ CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \
INCLUDES=-I..
LIBS=$(X_LIBS) $(XFT_LIBS) $(XINERAMA_LIBS) $(XKB_LIBS) $(XRANDR_LIBS) \
- $(VIDMODE_LIBS) $(XSHAPE_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) @LIBS@ \
- @LIBINTL@
+ $(VIDMODE_LIBS) $(XSHAPE_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) \
+ $(LIBSN_LIBS) @LIBS@ @LIBINTL@
bin_PROGRAMS=$(binary)
diff --git a/openbox/event.c b/openbox/event.c
index 900567c0..a2604bcf 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -21,6 +21,10 @@
#include <X11/Xatom.h>
#include <glib.h>
+#ifdef USE_LIBSN
+# include <libsn/sn.h>
+#endif
+
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
@@ -129,6 +133,10 @@ void event_loop()
}
XNextEvent(ob_display, &e);
+#ifdef USE_LIBSN
+ sn_display_process_event(ob_sn_display, &e);
+#endif
+
event_process(&e);
had_event = TRUE;
}
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 93e91a59..3b2a9991 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -118,7 +118,11 @@ int main(int argc, char **argv)
g_critical("Failed to set display as close-on-exec.");
exit(1);
}
-
+
+#ifdef USE_LIBSN
+ ob_sn_display = sn_display_new(ob_display, NULL, NULL);
+#endif
+
ob_screen = DefaultScreen(ob_display);
ob_root = RootWindow(ob_display, ob_screen);
@@ -140,6 +144,7 @@ int main(int argc, char **argv)
putenv(g_strdup_printf("DISPLAY=%s", DisplayString(ob_display)));
ob_cursors.ptr = XCreateFontCursor(ob_display, XC_left_ptr);
+ ob_cursors.busy = XCreateFontCursor(ob_display, XC_watch);
ob_cursors.move = XCreateFontCursor(ob_display, XC_fleur);
ob_cursors.tl = XCreateFontCursor(ob_display, XC_top_left_corner);
ob_cursors.tr = XCreateFontCursor(ob_display, XC_top_right_corner);
diff --git a/openbox/openbox.h b/openbox/openbox.h
index d747b3f7..51f62079 100644
--- a/openbox/openbox.h
+++ b/openbox/openbox.h
@@ -1,11 +1,21 @@
#ifndef __openbox_h
#define __openbox_h
+#ifdef USE_LIBSN
+# define SN_API_NOT_YET_FROZEN
+# include <libsn/sn.h>
+#endif
+
#include <glib.h>
#include <X11/Xlib.h>
/*! The X display */
extern Display *ob_display;
+
+#ifdef USE_LIBSN
+SnDisplay *ob_sn_display;
+#endif
+
/*! The number of the screen on which we're running */
extern int ob_screen;
/*! The root window */
@@ -36,6 +46,7 @@ extern gboolean ob_sync;
typedef struct Cursors {
Cursor ptr;
+ Cursor busy;
Cursor move;
Cursor bl;
Cursor br;
diff --git a/openbox/screen.c b/openbox/screen.c
index fd624466..044098fc 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -2,6 +2,7 @@
#include "dock.h"
#include "prop.h"
#include "startup.h"
+#include "timer.h"
#include "config.h"
#include "screen.h"
#include "client.h"
@@ -11,6 +12,11 @@
#include "extensions.h"
#include "../render/render.h"
+#ifdef USE_LIBSN
+# define SN_API_NOT_YET_FROZEN
+# include <libsn/sn.h>
+#endif
+
#include <X11/Xlib.h>
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
@@ -34,7 +40,16 @@ static Rect *area = NULL;
static Strut *strut = NULL;
static Window support_window = None;
+#ifdef USE_LIBSN
+static SnMonitorContext *sn_context;
+static int sn_busy_cnt;
+static Timer *sn_timer = NULL;
+
+static void sn_event_func(SnMonitorEvent *event, void *data);
+#endif
+
static void screen_update_area();
+static void set_root_cursor();
static gboolean running;
static int another_running(Display *d, XErrorEvent *e)
@@ -63,8 +78,7 @@ gboolean screen_annex()
g_message("Managing screen %d", ob_screen);
- /* set the mouse cursor for the root window (the default cursor) */
- XDefineCursor(ob_display, ob_root, ob_cursors.ptr);
+ set_root_cursor();
/* set the OPENBOX_PID hint */
pid = getpid();
@@ -187,6 +201,12 @@ void screen_startup()
PROP_SET32(ob_root, net_showing_desktop, cardinal, screen_showing_desktop);
screen_update_layout();
+
+#ifdef USE_LIBSN
+ sn_context = sn_monitor_context_new(ob_sn_display, ob_screen,
+ sn_event_func, NULL, NULL);
+ sn_busy_cnt = 0;
+#endif
}
void screen_shutdown()
@@ -599,3 +619,68 @@ Strut *screen_strut(guint desktop)
}
return &strut[desktop];
}
+
+static void set_root_cursor()
+{
+#ifdef USE_LIBSN
+ if (sn_busy_cnt)
+ XDefineCursor(ob_display, ob_root, ob_cursors.busy);
+ else
+#endif
+ XDefineCursor(ob_display, ob_root, ob_cursors.ptr);
+}
+
+#ifdef USE_LIBSN
+static void sn_timeout(void *data)
+{
+ timer_stop(sn_timer);
+ sn_timer = NULL;
+ sn_busy_cnt = 0;
+
+ set_root_cursor();
+}
+
+static void sn_event_func(SnMonitorEvent *ev, void *data)
+{
+ SnStartupSequence *seq;
+ const char *seq_id, *bin_name;
+ int cnt = sn_busy_cnt;
+
+ if (!(seq = sn_monitor_event_get_startup_sequence(ev)))
+ return;
+
+ seq_id = sn_startup_sequence_get_id(seq);
+ bin_name = sn_startup_sequence_get_binary_name(seq);
+
+ if (!(seq_id && bin_name))
+ return;
+
+ switch (sn_monitor_event_get_type(ev)) {
+ case SN_MONITOR_EVENT_INITIATED:
+ ++sn_busy_cnt;
+ if (sn_timer)
+ timer_stop(sn_timer);
+ /* 30 second timeout for apps to start */
+ sn_timer = timer_start(30 * 1000000, sn_timeout, NULL);
+ break;
+ case SN_MONITOR_EVENT_CHANGED:
+ break;
+ case SN_MONITOR_EVENT_COMPLETED:
+ if (sn_busy_cnt) --sn_busy_cnt;
+ if (sn_timer) {
+ timer_stop(sn_timer);
+ sn_timer = NULL;
+ }
+ break;
+ case SN_MONITOR_EVENT_CANCELED:
+ if (sn_busy_cnt) --sn_busy_cnt;
+ if (sn_timer) {
+ timer_stop(sn_timer);
+ sn_timer = NULL;
+ }
+ };
+
+ if (sn_busy_cnt != cnt)
+ set_root_cursor();
+}
+#endif