add find_or_start

This commit is contained in:
seanpringle
2012-08-31 14:44:51 +10:00
parent 9c912a7133
commit 008f4e3593
5 changed files with 80 additions and 5 deletions

View File

@@ -4,7 +4,7 @@ cerberus
* Designed for wide screens. * Designed for wide screens.
* Static tiling; you get just three fixed asymmetric tiles and windows never move automatically. * Static tiling; you get just three fixed asymmetric tiles and windows never move automatically.
* Bare minimum EWMH to support panels and [simpleswitcher](https://github.com/seanpringle/simpleswitcher) * Bare minimum EWMH to support panels and [simpleswitcher](https://github.com/seanpringle/simpleswitcher)
* A few keyboard controls for moving, focusing, cycling, closing. * A few keyboard controls for moving, focusing, cycling, closing, and finding windows.
* Transient windows and dialogs are centered on parent, not tiled. * Transient windows and dialogs are centered on parent, not tiled.
* Splash screens and notification popups are displayed as requested, not tiled. * Splash screens and notification popups are displayed as requested, not tiled.
* config.h for customization of borders and keys. * config.h for customization of borders and keys.

View File

@@ -30,6 +30,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "proto.h" #include "proto.h"
#include "config.h" #include "config.h"
void catch_exit(int sig)
{
while (0 < waitpid(-1, NULL, WNOHANG));
}
int execsh(char *cmd)
{
// use sh for args parsing
return execlp("/bin/sh", "sh", "-c", cmd, NULL);
}
// execute sub-process
pid_t exec_cmd(char *cmd)
{
if (!cmd || !cmd[0]) return -1;
signal(SIGCHLD, catch_exit);
pid_t pid = fork();
if (!pid)
{
setsid();
execsh(cmd);
exit(EXIT_FAILURE);
}
return pid;
}
// X error handler // X error handler
int oops(Display *d, XErrorEvent *ee) int oops(Display *d, XErrorEvent *ee)
{ {
@@ -477,6 +503,36 @@ void client_active(client *c)
ewmh_active_window(c->window); ewmh_active_window(c->window);
} }
// real simple switcher/launcher
void find_or_start(char *class)
{
int i; stack all;
memset(&all, 0, sizeof(stack));
windows_visible(&all);
client *found = NULL;
for (i = 0; !found && i < all.depth; i++)
{
XClassHint chint;
client *c = all.clients[i];
if (c && c->manage && XGetClassHint(display, c->window, &chint))
{
if (!strcasecmp(chint.res_class, class) || !strcasecmp(chint.res_name, class))
found = c;
XFree(chint.res_class);
XFree(chint.res_name);
}
}
if (found)
{
client_raise(found);
client_active(found);
return;
}
exec_cmd(class);
}
// client events we care about // client events we care about
void window_listen(Window win) void window_listen(Window win)
{ {
@@ -606,15 +662,16 @@ void key_press(XKeyEvent *e)
latest = e->time; latest = e->time;
client *c = window_client(current); client *c = window_client(current);
short act = ACTION_NONE; short act = ACTION_NONE; void *data = NULL;
KeySym key = XkbKeycodeToKeysym(display, e->keycode, 0, 0); KeySym key = XkbKeycodeToKeysym(display, e->keycode, 0, 0);
unsigned int state = e->state & ~(LockMask|NumlockMask); unsigned int state = e->state & ~(LockMask|NumlockMask);
for (i = 0; i < sizeof(keys)/sizeof(binding); i++) for (i = 0; i < sizeof(keys)/sizeof(binding); i++)
{ {
if (keys[i].key == key && keys[i].mod == state) if (keys[i].key == key && (keys[i].mod == AnyModifier || keys[i].mod == state))
{ {
act = keys[i].act; act = keys[i].act;
data = keys[i].data;
break; break;
} }
} }
@@ -656,6 +713,9 @@ void key_press(XKeyEvent *e)
case ACTION_FOCUS_SPOT3: case ACTION_FOCUS_SPOT3:
spot_active(SPOT3, None); spot_active(SPOT3, None);
break; break;
case ACTION_FIND_OR_START:
find_or_start(data);
break;
} }
client_free(c); client_free(c);
ewmh_client_list(); ewmh_client_list();
@@ -713,6 +773,7 @@ void focus_change(XFocusChangeEvent *e)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, j; int i, j;
signal(SIGCHLD, catch_exit);
if(!(display = XOpenDisplay(0))) return 1; if(!(display = XOpenDisplay(0))) return 1;
@@ -738,6 +799,9 @@ int main(int argc, char *argv[])
{ {
XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod, root, XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod, root,
True, GrabModeAsync, GrabModeAsync); True, GrabModeAsync, GrabModeAsync);
if (keys[i].mod == AnyModifier) continue;
XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|LockMask, root, XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|LockMask, root,
True, GrabModeAsync, GrabModeAsync); True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|NumlockMask, root, XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|NumlockMask, root,

View File

@@ -38,6 +38,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <err.h> #include <err.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -118,7 +120,7 @@ enum {
ACTION_CYCLE, ACTION_CYCLE,
ACTION_CLOSE, ACTION_CLOSE,
ACTION_OTHER, ACTION_OTHER,
ACTION_STATE, ACTION_FIND_OR_START,
ACTIONS ACTIONS
}; };
@@ -126,6 +128,7 @@ typedef struct {
unsigned int mod; unsigned int mod;
KeySym key; KeySym key;
short act; short act;
void *data;
} binding; } binding;
enum { enum {

View File

@@ -39,4 +39,9 @@ binding keys[] = {
// gracefully close the current window // gracefully close the current window
{ .mod = Mod4Mask, .key = XK_Escape, .act = ACTION_CLOSE }, { .mod = Mod4Mask, .key = XK_Escape, .act = ACTION_CLOSE },
// find or start apps by WM_CLASS (case insensitive)
{ .mod = AnyModifier, .key = XK_F1, .act = ACTION_FIND_OR_START, .data = "urxvt" },
{ .mod = AnyModifier, .key = XK_F2, .act = ACTION_FIND_OR_START, .data = "kate" },
{ .mod = AnyModifier, .key = XK_F3, .act = ACTION_FIND_OR_START, .data = "chromium" },
}; };

View File

@@ -1,3 +1,5 @@
void catch_exit(int sig);
int execsh(char *cmd);
int oops(Display *d, XErrorEvent *ee); int oops(Display *d, XErrorEvent *ee);
unsigned int color_get(const char *name); unsigned int color_get(const char *name);
int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, int bytes); int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, int bytes);
@@ -22,6 +24,7 @@ void client_stack(client *c, stack *all, stack *raise);
void client_raise(client *c); void client_raise(client *c);
void client_lower(client *c); void client_lower(client *c);
void client_active(client *c); void client_active(client *c);
void find_or_start(char *class);
void window_listen(Window win); void window_listen(Window win);
void client_review(client *c); void client_review(client *c);
void create_notify(XCreateWindowEvent *e); void create_notify(XCreateWindowEvent *e);