From 229d2b2c4d4a91e403db54f8698704f9251cfd5a Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 5 Sep 2022 16:03:55 -0700 Subject: [PATCH 1/6] [amiwm] Fix NULL scr issue If the clock timer fires when global scr is NULL then we end up calling redrawmenubar() with a NULL global scr, but a valid local scr. So just pass in the scr used when doing "stuff" into redrawmenubar(), making the 'scr' in redrawmenubar() also local scope. --- frame.c | 6 +++--- main.c | 16 ++++++++-------- menu.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/frame.c b/frame.c index cf4acfd..86ad2c2 100644 --- a/frame.c +++ b/frame.c @@ -28,7 +28,7 @@ extern Display *dpy; extern XContext client_context, screen_context; extern Cursor wm_curs; extern int shape_extn; -extern void redrawmenubar(Window); +extern void redrawmenubar(Scrn *, Window); void reshape_frame(Client *c); Window creategadget(Client *c, Window p, int x, int y, int w, int h) @@ -510,7 +510,7 @@ void clickenter() { if((scr=mbdscr)&& clickwindow == scr->menubardepth) { mbdclick = scr; - redrawmenubar(scr->menubardepth); + redrawmenubar(scr, scr->menubardepth); } else { scr = clickclient->scr; redraw(clickclient, clickclient->clicked=clickwindow); @@ -521,7 +521,7 @@ void clickleave() { if((scr=mbdscr)&& clickwindow == scr->menubardepth) { mbdclick = NULL; - redrawmenubar(scr->menubardepth); + redrawmenubar(scr, scr->menubardepth); } else { scr = clickclient->scr; clickclient->clicked=None; diff --git a/main.c b/main.c index a6f43d1..a49fb4b 100644 --- a/main.c +++ b/main.c @@ -88,7 +88,7 @@ extern Scrn *mbdclick, *mbdscr; extern void reparent(Client *); extern void redraw(Client *, Window); extern void redrawclient(Client *); -extern void redrawmenubar(Window); +extern void redrawmenubar(Scrn *, Window); extern void gadgetclicked(Client *c, Window w, XEvent *e); extern void gadgetunclicked(Client *c, XEvent *e); extern void gadgetaborted(Client *c); @@ -283,7 +283,7 @@ void restorescreentitle(Scrn *s) { (scr=s)->title=s->deftitle; XClearWindow(dpy, s->menubar); - redrawmenubar(s->menubar); + redrawmenubar(s, s->menubar); if(free_screentitle) { free(free_screentitle); free_screentitle=NULL; @@ -295,7 +295,7 @@ void wberror(Scrn *s, char *message) remove_call_out((void(*)(void *))restorescreentitle, s); (scr=s)->title=message; XClearWindow(dpy, s->menubar); - redrawmenubar(s->menubar); + redrawmenubar(s, s->menubar); XBell(dpy, 100); call_out(2, 0, (void(*)(void *))restorescreentitle, s); } @@ -828,7 +828,7 @@ static void update_clock(void *dontcare) scr = get_front_scr(); do { - redrawmenubar(scr->menubar); + redrawmenubar(scr, scr->menubar); scr=scr->behind; } while(scr != get_front_scr()); } @@ -1001,7 +1001,7 @@ int main(int argc, char *argv[]) else if(i) redrawicon(i, event.xexpose.window); else if(scr) - redrawmenubar(event.xexpose.window); + redrawmenubar(scr, event.xexpose.window); if((rubberclient || boundingscr)&&!prefs.opaquemove) drawrubber(); } break; @@ -1337,7 +1337,7 @@ int main(int argc, char *argv[]) } else if(scr&&event.xbutton.window==scr->menubardepth) { clickwindow=scr->menubardepth; mbdclick=mbdscr=scr; - redrawmenubar(scr->menubardepth); + redrawmenubar(scr, scr->menubardepth); } else if(scr&&event.xbutton.window==scr->menubar && scr->back!=scr->root) { startscreendragging(scr, &event); @@ -1352,7 +1352,7 @@ int main(int argc, char *argv[]) else if(scr&&(scr==mbdscr)&&clickwindow==scr->menubardepth) { mbdclick=NULL; clickwindow=None; - redrawmenubar(scr->menubardepth); + redrawmenubar(scr, scr->menubardepth); } else if(clickclient) gadgetaborted(clickclient); else if(dragiconlist) @@ -1386,7 +1386,7 @@ int main(int argc, char *argv[]) else if((scr=mbdscr)&& clickwindow==scr->menubardepth) { if(mbdclick) { mbdclick=NULL; - redrawmenubar(scr->menubardepth); + redrawmenubar(scr, scr->menubardepth); screentoback(); } clickwindow=None; diff --git a/menu.c b/menu.c index f5dd35b..169fedf 100644 --- a/menu.c +++ b/menu.c @@ -494,7 +494,7 @@ void createmenubar() * This takes in the target window, which may be the basic menubar, * a clicked-on menu, or the depth widget. */ -void redrawmenubar(Window w) +void redrawmenubar(Scrn *scr, Window w) { static const char defaultTimeFormat[] = "%c"; int widget_rhs; From 631176c9a290f0de8aae938690d41c4d5f41e969 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2022 18:54:13 -0700 Subject: [PATCH 2/6] [amiwm] Implement a keyboard shortcut to move a client to a different screen This allows a keyboard shortcut to move a client to a different amiwm screen. That way when you have things like Firefox restart every window in a single screen, you can quickly move screens to where they should be. --- MODULES.md | 2 +- client.c | 15 +++++++++++++++ client.h | 2 ++ icon.c | 4 ++++ kbdlexer.l | 1 + libami/libami.h | 1 + libami/mdscreen.c | 5 +++++ module.c | 15 +++++++++++++++ module.h | 1 + 9 files changed, 45 insertions(+), 1 deletion(-) diff --git a/MODULES.md b/MODULES.md index cf1182b..f71cef6 100644 --- a/MODULES.md +++ b/MODULES.md @@ -75,11 +75,11 @@ Currently the following are defined: rotatescreens - Move the frontmost screen to the back raisewindow - Rotate the bottom window to the top of the screen lowerwindow - Rotate the top window to the bottom of the screen +rotatewindow - Move the current window to the next screen, rotate screen front - Move the window in which the key is pressed to the front back - Move the window in which the key is pressed to the back iconify - Iconify the window in which the key is pressed - #### Example Module "Keyboard" "\ diff --git a/client.c b/client.c index c6378ab..f500cc5 100644 --- a/client.c +++ b/client.c @@ -379,3 +379,18 @@ void flushclients() rmclient(c); } } + +/* + * Reparent the given client to the given screen. + * + * This moves the given client to the given screen. + */ +void +reparent_client(Scrn *s, Client *client) +{ + client->scr = s; + if(client->parent != client->scr->root) + XReparentWindow(dpy, client->parent, s->back, client->x, client->y); + setstringprop(client->window, amiwm_screen, s->deftitle); + sendconfig(client); +} diff --git a/client.h b/client.h index 38ac54f..d8b3c82 100644 --- a/client.h +++ b/client.h @@ -51,5 +51,7 @@ extern void getstate(Client *); extern void grav_map_frame_to_win(Client *, int, int, int *, int *); extern void grav_map_win_to_frame(Client *, int, int, int *, int *); extern void setclientstate(Client *, int); +extern void reparent_client(struct _Scrn *s, Client *client); + #endif diff --git a/icon.c b/icon.c index 2db0d17..1745e60 100644 --- a/icon.c +++ b/icon.c @@ -156,12 +156,16 @@ void reparenticon(Icon *i, Scrn *s, int x, int y) i->next=s->icons; s->icons=i; if(i->client) { +#if 1 + reparent_client(s, i->client); +#else i->client->scr=s; if(i->client->parent != i->client->scr->root) XReparentWindow(dpy, i->client->parent, s->back, i->client->x, i->client->y); setstringprop(i->client->window, amiwm_screen, s->deftitle); sendconfig(i->client); +#endif } if(os) selecticon(i); diff --git a/kbdlexer.l b/kbdlexer.l index 3149834..8f75d78 100644 --- a/kbdlexer.l +++ b/kbdlexer.l @@ -44,6 +44,7 @@ int parse_keyword(char *str, YYSTYPE *val) { "lowerwindow", (mdfuncp)md_rotate_window_lower }, { "raisewindow", (mdfuncp)md_rotate_window_raise }, { "rotatescreens", (mdfuncp)k_rotscreens }, + { "rotatewindow", (mdfuncp)md_rotate_window_desktop }, }; #define N_FUNC (sizeof(functab)/sizeof(functab[0])) struct { char *name; int token, num; } kwtab[] = { diff --git a/libami/libami.h b/libami/libami.h index 5e9e662..ce35024 100644 --- a/libami/libami.h +++ b/libami/libami.h @@ -370,6 +370,7 @@ extern int md_iconify(Window); extern int md_errormsg(Window, char *); extern int md_rotate_window_raise(Window); extern int md_rotate_window_lower(Window); +extern int md_rotate_window_desktop(Window); /* eventdispatcher.c */ extern void cx_event_broker(int, unsigned long, int (*)(XEvent*)); diff --git a/libami/mdscreen.c b/libami/mdscreen.c index 9599c99..c52d981 100644 --- a/libami/mdscreen.c +++ b/libami/mdscreen.c @@ -32,6 +32,11 @@ int md_rotate_window_lower(XID id) return md_command00(id, MCMD_ROTATE_WINDOW_LOWER); } +int md_rotate_window_desktop(XID id) +{ + return md_command00(id, MCMD_WINDOW_MOVE_NEXT_DESKTOP); +} + int md_errormsg(Window id, char *str) { return md_command0(id, MCMD_ERRORMSG, str, strlen(str)); diff --git a/module.c b/module.c index bb9dba7..157008a 100644 --- a/module.c +++ b/module.c @@ -45,6 +45,7 @@ extern void remove_fd_from_set(int); extern void screentoback(); extern void raiselowerclient(Client *, int); extern void wberror(Scrn *, char *); +extern void reparent(Client *); extern Icon *createappicon(struct module *, Window, char *, Pixmap, Pixmap, Pixmap, int, int); @@ -525,6 +526,20 @@ static void handle_module_cmd(struct module *m, char *data, int data_len) reply_module(m, NULL, 0); break; } + case MCMD_WINDOW_MOVE_NEXT_DESKTOP: + /* Move the current window, if any, to the next desktop */ + c = NULL; + if(! XFindContext(dpy, id, client_context, (XPointer*)&c)) { + /* Get the current screen */ + scr=getscreen(id); + /* Rotate screen, get the now front screen */ + screentoback(); + scr = get_front_scr(); + /* Assign this client to next screen */ + reparent_client(scr, c); + } + reply_module(m, NULL, 0); + break; break; default: reply_module(m, NULL, -1); diff --git a/module.h b/module.h index 4d227dd..58fd094 100644 --- a/module.h +++ b/module.h @@ -17,6 +17,7 @@ #define MCMD_ROTATE_WINDOW_RAISE 19 #define MCMD_ROTATE_WINDOW_LOWER 20 #define MCMD_UPDATE_BATTERY 21 +#define MCMD_WINDOW_MOVE_NEXT_DESKTOP 22 struct mcmd_header { XID id; From 93863ec3966cb41dff46238e49e715b5307143da Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 23 Nov 2022 18:11:27 -0800 Subject: [PATCH 3/6] [amiwm] add a .gitignore so I don't see / commit .o files --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o From 9ce1822bff04fecd7c4619e9e12124bc9ef40e5f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 15 Jan 2023 20:51:47 -0800 Subject: [PATCH 4/6] [amiwm] remove now dead code. --- icon.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/icon.c b/icon.c index 1745e60..b0fc083 100644 --- a/icon.c +++ b/icon.c @@ -156,16 +156,7 @@ void reparenticon(Icon *i, Scrn *s, int x, int y) i->next=s->icons; s->icons=i; if(i->client) { -#if 1 reparent_client(s, i->client); -#else - i->client->scr=s; - if(i->client->parent != i->client->scr->root) - XReparentWindow(dpy, i->client->parent, s->back, - i->client->x, i->client->y); - setstringprop(i->client->window, amiwm_screen, s->deftitle); - sendconfig(i->client); -#endif } if(os) selecticon(i); From 1a8a15e24f2ab2f750503f86864f34313ee575e3 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 12 Jun 2023 11:37:16 -0700 Subject: [PATCH 5/6] [amiwm] add a missing Makefile depedency This isn't completely enough to make this build with gmake -j, but it's one of many things that are missing. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index c51b9ed..6e5ce37 100644 --- a/Makefile.in +++ b/Makefile.in @@ -66,7 +66,7 @@ lib_clean: menu.o: menu.c $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -DAMIWM_HOME=\"$(AMIWM_HOME)\" $< -rc.o: rc.c +rc.o: rc.c gram.h $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -DAMIWM_HOME=\"$(AMIWM_HOME)\" $< diskobject.o: diskobject.c From 87ba044ea4e146cc6829be6ee62ba3ef664a98fa Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 12 Jun 2023 11:38:42 -0700 Subject: [PATCH 6/6] [libami] handle EINTR from select() as a non-error EINTR is happening during suspend/resume, which was causing all of the modules to die (and requiring a restart of amiwm to re-run all of its modules.) This fixes things in FreeBSD suspend/resume so, well, the modules keep working. :) --- libami/module.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libami/module.c b/libami/module.c index ff1bdaa..76cbbec 100644 --- a/libami/module.c +++ b/libami/module.c @@ -81,6 +81,13 @@ md_wait_read_fd(void) return (0); } if (ret < 0) { + /* + * Note: this happens during things like system suspend/resume + * on FreeBSD. + */ + if (errno == EINTR) { + return (0); + } return (-1); } if (FD_ISSET(md_in_fd, &readfds)) {