wmstatus: add insomniac mode

This commit is contained in:
Přemysl Eric Janouch 2017-05-14 19:33:59 +02:00
parent 7e730c42bd
commit aed4436ed7
Signed by: p
GPG Key ID: B715679E3A361BE6
3 changed files with 127 additions and 30 deletions

View File

@ -22,7 +22,7 @@ set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
include (AddThreads)
find_package (PkgConfig REQUIRED)
pkg_check_modules (dependencies REQUIRED libpulse x11 xext xextproto)
pkg_check_modules (dependencies REQUIRED libpulse x11 xext xextproto dbus-1)
pkg_check_modules (gdm gdm glib-2.0 gio-2.0)
option (WITH_GDM "Compile with GDM support" ${gdm_FOUND})

View File

@ -36,7 +36,7 @@ https://build.opensuse.org/project/repositories/home:pjanouch:git
Building
--------
Build dependencies: CMake, pkg-config, liberty (included) +
Runtime dependencies: libpulse, libx11, libgdm (optional)
Runtime dependencies: libpulse, libx11, dbus-1, libgdm (optional)
$ git clone --recursive https://github.com/pjanouch/desktop-tools.git
$ mkdir desktop-tools/build
@ -59,6 +59,8 @@ Use this project's GitHub to report any bugs, request features, or submit pull
requests. If you want to discuss this project, or maybe just hang out with
the developer, feel free to join me at irc://irc.janouch.name, channel #dev.
Bitcoin donations: 12r5uEWEgcHC46xd64tt3hHt9EUvYYDHe9
License
-------
'desktop-tools' is written by Přemysl Janouch <p.janouch@gmail.com>.

View File

@ -42,6 +42,8 @@
#include <pulse/introspect.h>
#include <pulse/subscribe.h>
#include <dbus/dbus.h>
// --- Utilities ---------------------------------------------------------------
enum { PIPE_READ, PIPE_WRITE };
@ -1168,6 +1170,12 @@ struct app_context
struct poller_fd x_event; ///< X11 event
char *layout; ///< Keyboard layout
// Insomnia:
DBusConnection *system_bus; ///< System bus connection
char *insomnia_info; ///< Status message (possibly error)
int insomnia_fd; ///< Inhibiting file descriptor
// MPD:
struct poller_timer mpd_reconnect; ///< Start MPD communication
@ -1233,6 +1241,16 @@ app_context_init (struct app_context *self)
poller_fd_init (&self->x_event, &self->poller,
ConnectionNumber (self->dpy));
// So far we don't necessarily need DBus to function,
// and we have no desire to process any incoming messages either
DBusError err = DBUS_ERROR_INIT;
self->insomnia_fd = -1;
if (!(self->system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &err)))
{
print_error ("dbus: %s", err.message);
dbus_error_free (&err);
}
mpd_client_init (&self->mpd_client, &self->poller);
nut_client_init (&self->nut_client, &self->poller);
@ -1264,6 +1282,10 @@ app_context_free (struct app_context *self)
}
str_free (&self->command_buffer);
free (self->insomnia_info);
if (self->insomnia_fd != -1)
xclose (self->insomnia_fd);
mpd_client_free (&self->mpd_client);
free (self->mpd_song);
free (self->mpd_status);
@ -1492,6 +1514,9 @@ refresh_status (struct app_context *ctx)
if (ctx->nut_status) ctx->backend->add (ctx->backend, ctx->nut_status);
if (ctx->layout) ctx->backend->add (ctx->backend, ctx->layout);
if (ctx->insomnia_info)
ctx->backend->add (ctx->backend, ctx->insomnia_info);
for (size_t i = 0; i < ctx->command_current.len; i++)
ctx->backend->add (ctx->backend, ctx->command_current.vector[i]);
@ -2353,6 +2378,75 @@ on_standby (struct app_context *ctx, int arg)
spawn ((char *[]) { "sh", "-c", "sleep 1; xset dpms force standby", NULL });
}
static void
go_insomniac (struct app_context *ctx)
{
static const char *what = "sleep:idle";
static const char *who = PROGRAM_NAME;
static const char *why = "";
static const char *mode = "block";
if (!ctx->system_bus)
{
ctx->insomnia_info = xstrdup_printf ("%s: %s", "Insomnia", "no DBus");
return;
}
DBusMessage *msg = dbus_message_new_method_call
("org.freedesktop.login1", "/org/freedesktop/login1",
"org.freedesktop.login1.Manager", "Inhibit");
hard_assert (msg != NULL);
hard_assert (dbus_message_append_args (msg,
DBUS_TYPE_STRING, &what,
DBUS_TYPE_STRING, &who,
DBUS_TYPE_STRING, &why,
DBUS_TYPE_STRING, &mode,
DBUS_TYPE_INVALID));
DBusError err = DBUS_ERROR_INIT;
DBusMessage *reply = dbus_connection_send_with_reply_and_block
(ctx->system_bus, msg, 1000, &err);
dbus_message_unref (msg);
if (!reply)
{
ctx->insomnia_info = xstrdup_printf ("%s: %s", "Insomnia", err.message);
dbus_error_free (&err);
}
else if (!dbus_message_get_args (reply, &err,
DBUS_TYPE_UNIX_FD, &ctx->insomnia_fd, DBUS_TYPE_INVALID))
{
dbus_message_unref (reply);
ctx->insomnia_info = xstrdup_printf ("%s: %s", "Insomnia", err.message);
dbus_error_free (&err);
}
else
{
dbus_message_unref (reply);
ctx->insomnia_info = xstrdup ("Insomniac");
set_cloexec (ctx->insomnia_fd);
}
}
static void
on_insomnia (struct app_context *ctx, int arg)
{
(void) arg;
free (ctx->insomnia_info);
ctx->insomnia_info = NULL;
// Get rid of the lock if we hold one, establish it otherwise
if (ctx->insomnia_fd != -1)
{
xclose (ctx->insomnia_fd);
ctx->insomnia_fd = -1;
}
else
go_insomniac (ctx);
refresh_status (ctx);
}
static void
on_lock_group (struct app_context *ctx, int arg)
{
@ -2369,48 +2463,49 @@ struct
g_keys[] =
{
// This key should be labeled L on normal Qwert[yz] layouts
{ Mod4Mask, XK_n, on_lock, 0 },
{ Mod4Mask, XK_n, on_lock, 0 },
// MPD
{ Mod4Mask, XK_Up, on_mpd_play, 0 },
{ Mod4Mask, XK_Down, on_mpd_stop, 0 },
{ Mod4Mask, XK_Left, on_mpd_prev, 0 },
{ Mod4Mask, XK_Right, on_mpd_next, 0 },
{ Mod4Mask, XK_Up, on_mpd_play, 0 },
{ Mod4Mask, XK_Down, on_mpd_stop, 0 },
{ Mod4Mask, XK_Left, on_mpd_prev, 0 },
{ Mod4Mask, XK_Right, on_mpd_next, 0 },
/* xmodmap | grep -e Alt_R -e Meta_R -e ISO_Level3_Shift -e Mode_switch */
{ Mod4Mask | Mod5Mask, XK_Left, on_mpd_backward, 0 },
{ Mod4Mask | Mod5Mask, XK_Right, on_mpd_forward, 0 },
{ Mod4Mask | Mod5Mask, XK_Left, on_mpd_backward, 0 },
{ Mod4Mask | Mod5Mask, XK_Right, on_mpd_forward, 0 },
// Display input sources
{ Mod4Mask, XK_F5, on_input_switch, 0 },
{ Mod4Mask, XK_F6, on_input_switch, 1 },
{ Mod4Mask, XK_F7, on_input_switch, 2 },
{ Mod4Mask, XK_F8, on_input_switch, 3 },
{ Mod4Mask, XK_F5, on_input_switch, 0 },
{ Mod4Mask, XK_F6, on_input_switch, 1 },
{ Mod4Mask, XK_F7, on_input_switch, 2 },
{ Mod4Mask, XK_F8, on_input_switch, 3 },
// Keyboard groups
{ Mod4Mask, XK_F9, on_lock_group, 0 },
{ Mod4Mask, XK_F10, on_lock_group, 1 },
{ Mod4Mask, XK_F11, on_lock_group, 2 },
{ Mod4Mask, XK_F12, on_lock_group, 3 },
{ Mod4Mask, XK_F9, on_lock_group, 0 },
{ Mod4Mask, XK_F10, on_lock_group, 1 },
{ Mod4Mask, XK_F11, on_lock_group, 2 },
{ Mod4Mask, XK_F12, on_lock_group, 3 },
// Brightness
{ Mod4Mask, XK_Home, on_brightness, 10 },
{ Mod4Mask, XK_End, on_brightness, -10 },
{ Mod4Mask, XK_Home, on_brightness, 10 },
{ Mod4Mask, XK_End, on_brightness, -10 },
{ 0, XF86XK_MonBrightnessUp, on_brightness, 10 },
{ 0, XF86XK_MonBrightnessDown, on_brightness, -10 },
{ Mod4Mask, XK_Pause, on_standby, 0 },
{ Mod4Mask, XK_Pause, on_standby, 0 },
{ Mod4Mask | ShiftMask, XK_Pause, on_insomnia, 0 },
// Volume
{ Mod4Mask, XK_Insert, on_volume_switch, 0 },
{ Mod4Mask, XK_Delete, on_volume_mute, 0 },
{ Mod4Mask, XK_Page_Up, on_volume_set, 5 },
{ Mod4Mask | Mod5Mask, XK_Page_Up, on_volume_set, 1 },
{ Mod4Mask, XK_Page_Down, on_volume_set, -5 },
{ Mod4Mask | Mod5Mask, XK_Page_Down, on_volume_set, -1 },
{ 0, XF86XK_AudioMicMute, on_volume_mic_mute, 0 },
{ 0, XF86XK_AudioMute, on_volume_mute, 0 },
{ 0, XF86XK_AudioRaiseVolume, on_volume_set, 5 },
{ 0, XF86XK_AudioLowerVolume, on_volume_set, -5 },
{ Mod4Mask, XK_Insert, on_volume_switch, 0 },
{ Mod4Mask, XK_Delete, on_volume_mute, 0 },
{ Mod4Mask, XK_Page_Up, on_volume_set, 5 },
{ Mod4Mask | Mod5Mask, XK_Page_Up, on_volume_set, 1 },
{ Mod4Mask, XK_Page_Down, on_volume_set, -5 },
{ Mod4Mask | Mod5Mask, XK_Page_Down, on_volume_set, -1 },
{ 0, XF86XK_AudioMicMute, on_volume_mic_mute, 0 },
{ 0, XF86XK_AudioMute, on_volume_mute, 0 },
{ 0, XF86XK_AudioRaiseVolume, on_volume_set, 5 },
{ 0, XF86XK_AudioLowerVolume, on_volume_set, -5 },
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -