add (optional) support for showing a busy cursor via startup notification
This commit is contained in:
parent
c912b634ab
commit
2b2beddc74
6 changed files with 123 additions and 7 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue