Automated update
This commit is contained in:
Binary file not shown.
@@ -633,6 +633,7 @@ clientmessage(XEvent *e)
|
|||||||
XSetWindowAttributes swa;
|
XSetWindowAttributes swa;
|
||||||
XClientMessageEvent *cme = &e->xclient;
|
XClientMessageEvent *cme = &e->xclient;
|
||||||
Client *c = wintoclient(cme->window);
|
Client *c = wintoclient(cme->window);
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
|
if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
|
||||||
/* add systray icons */
|
/* add systray icons */
|
||||||
@@ -689,8 +690,14 @@ clientmessage(XEvent *e)
|
|||||||
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|
||||||
|| cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */));
|
|| cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */));
|
||||||
} else if (cme->message_type == netatom[NetActiveWindow]) {
|
} else if (cme->message_type == netatom[NetActiveWindow]) {
|
||||||
if (c != selmon->sel && !c->isurgent)
|
for (i = 0; i < LENGTH(tags) && !((1 << i) & c->tags); i++);
|
||||||
seturgent(c, 1);
|
if (i < LENGTH(tags)) {
|
||||||
|
const Arg a = {.ui = 1 << i};
|
||||||
|
selmon = c->mon;
|
||||||
|
view(&a);
|
||||||
|
focus(c);
|
||||||
|
restack(selmon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
@@ -86,9 +87,21 @@ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms *
|
|||||||
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
||||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
||||||
|
|
||||||
|
typedef struct TagState TagState;
|
||||||
|
struct TagState {
|
||||||
|
int selected;
|
||||||
|
int occupied;
|
||||||
|
int urgent;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ClientState ClientState;
|
||||||
|
struct ClientState {
|
||||||
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
|
};
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
int i;
|
long i;
|
||||||
unsigned int ui;
|
unsigned long ui;
|
||||||
float f;
|
float f;
|
||||||
const void *v;
|
const void *v;
|
||||||
} Arg;
|
} Arg;
|
||||||
@@ -117,6 +130,7 @@ struct Client {
|
|||||||
Client *snext;
|
Client *snext;
|
||||||
Monitor *mon;
|
Monitor *mon;
|
||||||
Window win;
|
Window win;
|
||||||
|
ClientState prevstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -135,6 +149,7 @@ typedef struct {
|
|||||||
typedef struct Pertag Pertag;
|
typedef struct Pertag Pertag;
|
||||||
struct Monitor {
|
struct Monitor {
|
||||||
char ltsymbol[16];
|
char ltsymbol[16];
|
||||||
|
char lastltsymbol[16];
|
||||||
float mfact;
|
float mfact;
|
||||||
int nmaster;
|
int nmaster;
|
||||||
int num;
|
int num;
|
||||||
@@ -145,14 +160,17 @@ struct Monitor {
|
|||||||
unsigned int seltags;
|
unsigned int seltags;
|
||||||
unsigned int sellt;
|
unsigned int sellt;
|
||||||
unsigned int tagset[2];
|
unsigned int tagset[2];
|
||||||
|
TagState tagstate;
|
||||||
int showbar;
|
int showbar;
|
||||||
int topbar;
|
int topbar;
|
||||||
Client *clients;
|
Client *clients;
|
||||||
Client *sel;
|
Client *sel;
|
||||||
|
Client *lastsel;
|
||||||
Client *stack;
|
Client *stack;
|
||||||
Monitor *next;
|
Monitor *next;
|
||||||
Window barwin;
|
Window barwin;
|
||||||
const Layout *lt[2];
|
const Layout *lt[2];
|
||||||
|
const Layout *lastlt;
|
||||||
Pertag *pertag;
|
Pertag *pertag;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,6 +229,7 @@ static unsigned int getsystraywidth();
|
|||||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
||||||
static void grabbuttons(Client *c, int focused);
|
static void grabbuttons(Client *c, int focused);
|
||||||
static void grabkeys(void);
|
static void grabkeys(void);
|
||||||
|
static int handlexevent(struct epoll_event *ev);
|
||||||
static void incnmaster(const Arg *arg);
|
static void incnmaster(const Arg *arg);
|
||||||
static void keypress(XEvent *e);
|
static void keypress(XEvent *e);
|
||||||
static void killclient(const Arg *arg);
|
static void killclient(const Arg *arg);
|
||||||
@@ -241,8 +260,10 @@ static void setclientstate(Client *c, long state);
|
|||||||
static void setfocus(Client *c);
|
static void setfocus(Client *c);
|
||||||
static void setfullscreen(Client *c, int fullscreen);
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
static void setlayout(const Arg *arg);
|
static void setlayout(const Arg *arg);
|
||||||
|
static void setlayoutsafe(const Arg *arg);
|
||||||
static void setmfact(const Arg *arg);
|
static void setmfact(const Arg *arg);
|
||||||
static void setup(void);
|
static void setup(void);
|
||||||
|
static void setupepoll(void);
|
||||||
static void seturgent(Client *c, int urg);
|
static void seturgent(Client *c, int urg);
|
||||||
static void showhide(Client *c);
|
static void showhide(Client *c);
|
||||||
static void sigchld(int unused);
|
static void sigchld(int unused);
|
||||||
@@ -317,6 +338,8 @@ static void (*handler[LASTEvent]) (XEvent *) = {
|
|||||||
[UnmapNotify] = unmapnotify
|
[UnmapNotify] = unmapnotify
|
||||||
};
|
};
|
||||||
static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
|
static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
|
||||||
|
static int epoll_fd;
|
||||||
|
static int dpy_fd;
|
||||||
static int restart = 0;
|
static int restart = 0;
|
||||||
static int running = 1;
|
static int running = 1;
|
||||||
static Cur *cursor[CurLast];
|
static Cur *cursor[CurLast];
|
||||||
@@ -324,13 +347,20 @@ static Clr **scheme;
|
|||||||
static Clr **tagscheme;
|
static Clr **tagscheme;
|
||||||
static Display *dpy;
|
static Display *dpy;
|
||||||
static Drw *drw;
|
static Drw *drw;
|
||||||
static Monitor *mons, *selmon;
|
static Monitor *mons, *selmon, *lastselmon;
|
||||||
static Window root, wmcheckwin;
|
static Window root, wmcheckwin;
|
||||||
static KeySym keychain = -1;
|
static KeySym keychain = -1;
|
||||||
|
|
||||||
|
#include "ipc.h"
|
||||||
/* configuration, allows nested code to access above variables */
|
/* configuration, allows nested code to access above variables */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef VERSION
|
||||||
|
#include "IPCClient.c"
|
||||||
|
#include "yajl_dumps.c"
|
||||||
|
#include "ipc.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Pertag {
|
struct Pertag {
|
||||||
unsigned int curtag, prevtag; /* current and previous tag */
|
unsigned int curtag, prevtag; /* current and previous tag */
|
||||||
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
||||||
@@ -572,6 +602,12 @@ cleanup(void)
|
|||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
|
||||||
XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
|
||||||
|
|
||||||
|
ipc_cleanup();
|
||||||
|
|
||||||
|
if (close(epoll_fd) < 0) {
|
||||||
|
fprintf(stderr, "Failed to close epoll file descriptor\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1337,6 +1373,25 @@ grabkeys(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
handlexevent(struct epoll_event *ev)
|
||||||
|
{
|
||||||
|
if (ev->events & EPOLLIN) {
|
||||||
|
XEvent ev;
|
||||||
|
while (running && XPending(dpy)) {
|
||||||
|
XNextEvent(dpy, &ev);
|
||||||
|
if (handler[ev.type]) {
|
||||||
|
handler[ev.type](&ev); /* call handler */
|
||||||
|
ipc_send_events(mons, &lastselmon, selmon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ev-> events & EPOLLHUP) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
incnmaster(const Arg *arg)
|
incnmaster(const Arg *arg)
|
||||||
{
|
{
|
||||||
@@ -1821,12 +1876,40 @@ restack(Monitor *m)
|
|||||||
void
|
void
|
||||||
run(void)
|
run(void)
|
||||||
{
|
{
|
||||||
XEvent ev;
|
int event_count = 0;
|
||||||
/* main event loop */
|
const int MAX_EVENTS = 10;
|
||||||
|
struct epoll_event events[MAX_EVENTS];
|
||||||
|
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
while (running && !XNextEvent(dpy, &ev))
|
|
||||||
if (handler[ev.type])
|
/* main event loop */
|
||||||
handler[ev.type](&ev); /* call handler */
|
while (running) {
|
||||||
|
event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
||||||
|
|
||||||
|
for (int i = 0; i < event_count; i++) {
|
||||||
|
int event_fd = events[i].data.fd;
|
||||||
|
DEBUG("Got event from fd %d\n", event_fd);
|
||||||
|
|
||||||
|
if (event_fd == dpy_fd) {
|
||||||
|
// -1 means EPOLLHUP
|
||||||
|
if (handlexevent(events + i) == -1)
|
||||||
|
return;
|
||||||
|
} else if (event_fd == ipc_get_sock_fd()) {
|
||||||
|
ipc_handle_socket_epoll_event(events + i);
|
||||||
|
} else if (ipc_is_client_registered(event_fd)){
|
||||||
|
if (ipc_handle_client_epoll_event(events + i, mons, &lastselmon, selmon,
|
||||||
|
tags, LENGTH(tags), layouts, LENGTH(layouts)) < 0) {
|
||||||
|
fprintf(stderr, "Error handling IPC event on fd %d\n", event_fd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Got event from unknown fd %d, ptr %p, u32 %d, u64 %lu",
|
||||||
|
event_fd, events[i].data.ptr, events[i].data.u32,
|
||||||
|
events[i].data.u64);
|
||||||
|
fprintf(stderr, " with events %d\n", events[i].events);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2044,6 +2127,18 @@ setlayout(const Arg *arg)
|
|||||||
drawbar(selmon);
|
drawbar(selmon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setlayoutsafe(const Arg *arg)
|
||||||
|
{
|
||||||
|
const Layout *ltptr = (Layout *)arg->v;
|
||||||
|
if (ltptr == 0)
|
||||||
|
setlayout(arg);
|
||||||
|
for (int i = 0; i < LENGTH(layouts); i++) {
|
||||||
|
if (ltptr == &layouts[i])
|
||||||
|
setlayout(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* arg > 1.0 will set mfact absolutely */
|
/* arg > 1.0 will set mfact absolutely */
|
||||||
void
|
void
|
||||||
setmfact(const Arg *arg)
|
setmfact(const Arg *arg)
|
||||||
@@ -2146,6 +2241,36 @@ setup(void)
|
|||||||
XSelectInput(dpy, root, wa.event_mask);
|
XSelectInput(dpy, root, wa.event_mask);
|
||||||
grabkeys();
|
grabkeys();
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
|
setupepoll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setupepoll(void)
|
||||||
|
{
|
||||||
|
epoll_fd = epoll_create1(0);
|
||||||
|
dpy_fd = ConnectionNumber(dpy);
|
||||||
|
struct epoll_event dpy_event;
|
||||||
|
|
||||||
|
// Initialize struct to 0
|
||||||
|
memset(&dpy_event, 0, sizeof(dpy_event));
|
||||||
|
|
||||||
|
DEBUG("Display socket is fd %d\n", dpy_fd);
|
||||||
|
|
||||||
|
if (epoll_fd == -1) {
|
||||||
|
fputs("Failed to create epoll file descriptor", stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
dpy_event.events = EPOLLIN;
|
||||||
|
dpy_event.data.fd = dpy_fd;
|
||||||
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dpy_fd, &dpy_event)) {
|
||||||
|
fputs("Failed to add display file descriptor to epoll", stderr);
|
||||||
|
close(epoll_fd);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipc_init(ipcsockpath, epoll_fd, ipccommands, LENGTH(ipccommands)) < 0) {
|
||||||
|
fputs("Failed to initialize IPC\n", stderr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2749,10 +2874,18 @@ updatesystray(void)
|
|||||||
void
|
void
|
||||||
updatetitle(Client *c)
|
updatetitle(Client *c)
|
||||||
{
|
{
|
||||||
|
char oldname[sizeof(c->name)];
|
||||||
|
strcpy(oldname, c->name);
|
||||||
|
|
||||||
if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
|
if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
|
||||||
gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
|
gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
|
||||||
if (c->name[0] == '\0') /* hack to mark broken clients */
|
if (c->name[0] == '\0') /* hack to mark broken clients */
|
||||||
strcpy(c->name, broken);
|
strcpy(c->name, broken);
|
||||||
|
|
||||||
|
for (Monitor *m = mons; m; m = m->next) {
|
||||||
|
if (m->sel == c && strcmp(oldname, c->name) != 0)
|
||||||
|
ipc_focused_title_change_event(m->num, c->win, oldname, c->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Binary file not shown.
57
KleinDwm/source/patches/dwm-focusonnetactive-6.2.diff
Normal file
57
KleinDwm/source/patches/dwm-focusonnetactive-6.2.diff
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
From 286ca3bb1af08b452bf8140abcc23d4ef61baaa2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Tue, 7 Apr 2020 12:33:04 +0200
|
||||||
|
Subject: [PATCH] Activate a window in response to _NET_ACTIVE_WINDOW
|
||||||
|
|
||||||
|
By default, dwm response to client requests to _NET_ACTIVE_WINDOW client
|
||||||
|
messages by setting the urgency bit on the named window.
|
||||||
|
|
||||||
|
This patch activates the window instead.
|
||||||
|
|
||||||
|
Both behaviours are legitimate according to
|
||||||
|
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472702304
|
||||||
|
|
||||||
|
One should decide which of these one should perform based on the message
|
||||||
|
senders' untestable claims that it represents the end-user. Setting the
|
||||||
|
urgency bit is the conservative decision. This patch implements the more
|
||||||
|
trusting alternative.
|
||||||
|
|
||||||
|
It also allows dwm to work with `wmctrl -a` and other external window
|
||||||
|
management utilities
|
||||||
|
|
||||||
|
---
|
||||||
|
dwm.c | 11 +++++++++--
|
||||||
|
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..3919d47 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -514,6 +514,7 @@ clientmessage(XEvent *e)
|
||||||
|
{
|
||||||
|
XClientMessageEvent *cme = &e->xclient;
|
||||||
|
Client *c = wintoclient(cme->window);
|
||||||
|
+ unsigned int i;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
return;
|
||||||
|
@@ -523,8 +524,14 @@ clientmessage(XEvent *e)
|
||||||
|
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|
||||||
|
|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
|
||||||
|
} else if (cme->message_type == netatom[NetActiveWindow]) {
|
||||||
|
- if (c != selmon->sel && !c->isurgent)
|
||||||
|
- seturgent(c, 1);
|
||||||
|
+ for (i = 0; i < LENGTH(tags) && !((1 << i) & c->tags); i++);
|
||||||
|
+ if (i < LENGTH(tags)) {
|
||||||
|
+ const Arg a = {.ui = 1 << i};
|
||||||
|
+ selmon = c->mon;
|
||||||
|
+ view(&a);
|
||||||
|
+ focus(c);
|
||||||
|
+ restack(selmon);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
||||||
Reference in New Issue
Block a user