add find_or_start
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
68
cerberus.c
68
cerberus.c
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
5
config.h
5
config.h
@@ -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" },
|
||||||
};
|
};
|
||||||
|
|||||||
3
proto.h
3
proto.h
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user