From 400c608f2d792e7d41d1126203a96b05aa3ab4b5 Mon Sep 17 00:00:00 2001 From: Mike Hewitt Date: Tue, 13 Sep 2022 16:01:49 -0400 Subject: [PATCH 1/2] added configuration options for issue #585 (kill menu, client name in title) --- jwm.1.in | 23 +++++++++++++++++++++-- src/border.c | 15 +++++++++++++-- src/parse.c | 22 ++++++++++++++++++++++ src/settings.c | 3 +++ src/settings.h | 10 +++++++++- src/winmenu.c | 4 +++- 6 files changed, 71 insertions(+), 6 deletions(-) diff --git a/jwm.1.in b/jwm.1.in index ab3dc5a7..1c4f650c 100644 --- a/jwm.1.in +++ b/jwm.1.in @@ -1074,7 +1074,7 @@ that the value is relative to the bottom of the screen. .B "WINDOW STYLE" .RS The \fBWindowStyle\fP tag controls the look of window borders. -This tag supports the following attribute: +This tag supports the following attributes: .P .B decorations .RS @@ -1082,6 +1082,18 @@ The window decorations to use. Valid options are \fBflat\fP and \fBmotif\fP. \fBflat\fP is the default. .RE .P +.B machinename +.RS +Include the X client machine name (WM_CLIENT_MACHINE) in the window title. +Valid options are \fBtrue\fP and \fBfalse\fP. \fBfalse\fP is the default. +.RE +.P +.B delimiters +.RS +The two characters used to wrap the X client machine name in the window title. +The default characters are \fB()\fP. +.RE +.P Within this tag, the following tags are supported: .P .B Font @@ -1257,7 +1269,7 @@ respectively. .B "TASK LIST STYLE" .RS The \fBTaskListStyle\fP tag controls the look of task lists. -The following attributea are supported: +The following attributes are supported: .P .B decorations .RS @@ -1279,6 +1291,13 @@ Possible values are \fBdesktop\fP and \fBall\fP. The default is \fBdesktop\fP. .RE .P +.B killmenu +.RS +Determines if the \fBKill\fP popup menu item is shown on task bars and +window title bars. Possible values are \fBtrue\fP and \fBfalse\fP. The default +is \fBtrue\fP. +.RE +.P Within this tag the following tags are supported: .P .B Font diff --git a/src/border.c b/src/border.c index df4245d9..5c5759ae 100644 --- a/src/border.c +++ b/src/border.c @@ -451,7 +451,17 @@ void DrawBorderHelper(const ClientNode *np) if(np->name && np->name[0] && point.x < point.y) { unsigned titleWidth = point.y - point.x; const int sheight = GetStringHeight(FONT_BORDER); - const int textWidth = GetStringWidth(FONT_BORDER, np->name); + const int buffSize = (MAX_TITLE_LENGTH+1)*sizeof(char); + char *titleBuffer = calloc(MAX_TITLE_LENGTH+1,sizeof(char)); + titleBuffer = memset(titleBuffer,'\0',buffSize); + if (settings.showMachineName){ + sprintf(titleBuffer,"%s %c%s%c",np->name, + settings.machineNameDelimiters[0],np->machineName, + settings.machineNameDelimiters[1]); + } else { + sprintf(titleBuffer,"%s",np->name); + } + const int textWidth = GetStringWidth(FONT_BORDER,titleBuffer); unsigned titlex, titley; int xoffset = 0; @@ -474,7 +484,8 @@ void DrawBorderHelper(const ClientNode *np) titley += south - 1; } RenderString(canvas, FONT_BORDER, borderTextColor, - titlex, titley, titleWidth, np->name); + titlex, titley, titleWidth, titleBuffer); + free(titleBuffer); } } diff --git a/src/parse.c b/src/parse.c index 5119f66d..c66e3741 100644 --- a/src/parse.c +++ b/src/parse.c @@ -160,6 +160,9 @@ static const char *DYNAMIC_ATTRIBUTE = "dynamic"; static const char *SPACING_ATTRIBUTE = "spacing"; static const char *TIMEOUT_ATTRIBUTE = "timeout"; static const char *POPUP_ATTRIBUTE = "popup"; +static const char *MACHINENAME_ATTRIBUTE = "machinename"; +static const char *MN_DELIMITERS_ATTRIBUTE = "delimiters"; +static const char *KILL_MENU_ATTRIBUTE = "killmenu"; static const char *FALSE_VALUE = "false"; static const char *TRUE_VALUE = "true"; @@ -998,6 +1001,19 @@ void ParseWindowStyle(const TokenNode *tp) { const TokenNode *np; + const char *temp; + temp = FindAttribute(tp->attributes, MACHINENAME_ATTRIBUTE); + if(temp){ + settings.showMachineName = !strcmp(temp,TRUE_VALUE); + } + + temp = FindAttribute(tp->attributes, MN_DELIMITERS_ATTRIBUTE); + if(temp && strlen(temp)>=2) { + char *delims = calloc(strlen(temp)+1,sizeof(char)); + sprintf(delims,"%s",temp); + settings.machineNameDelimiters = delims; + } + ParseDecorations(tp, &settings.windowDecorations); for(np = tp->subnodeHead; np; np = np->next) { switch(np->type) { @@ -1203,6 +1219,12 @@ void ParseTrayStyle(const TokenNode *tp, FontType font, ColorType fg) if(temp) { settings.listAllTasks = !strcmp(temp, "all"); } + + temp = FindAttribute(tp->attributes, KILL_MENU_ATTRIBUTE); + if(temp) { + settings.showKillMenuItem = !strcmp(temp, TRUE_VALUE); + } + } else if(tp->type == TOK_TRAYSTYLE) { ParseDecorations(tp, &settings.trayDecorations); } diff --git a/src/settings.c b/src/settings.c index b057519c..ddaf5340 100644 --- a/src/settings.c +++ b/src/settings.c @@ -61,6 +61,9 @@ void InitializeSettings(void) settings.groupTasks = 0; settings.listAllTasks = 0; settings.dockSpacing = 0; + settings.showMachineName = 0; + settings.machineNameDelimiters = DEFAULT_MACHINE_NAME_DELIMITERS; + settings.showKillMenuItem = 1; memcpy(settings.titleBarLayout, DEFAULT_TITLE_BAR_LAYOUT, sizeof(settings.titleBarLayout)); } diff --git a/src/settings.h b/src/settings.h index cb7733b2..2c25b8f0 100644 --- a/src/settings.h +++ b/src/settings.h @@ -84,10 +84,15 @@ typedef unsigned char DesktopBackAndForthType; #define DBACKANDFORTH_OFF 0 /**< No back and forth */ #define DBACKANDFORTH_ON 1 /**< Enable back and forth */ -/** Maximimum number of title bar components +/** Maximum number of title bar components * For now, we allow each component to be used twice. */ #define TBC_COUNT 9 +/** Maximum number of characters in window title + * and default characters for machine name delimiters. */ +#define MAX_TITLE_LENGTH 512 +#define DEFAULT_MACHINE_NAME_DELIMITERS "()" + /** Settings. */ typedef struct { unsigned doubleClickSpeed; @@ -122,6 +127,9 @@ typedef struct { MouseContextType titleBarLayout[TBC_COUNT + 1]; char groupTasks; char listAllTasks; + char showMachineName; + char *machineNameDelimiters; + char showKillMenuItem; DesktopBackAndForthType desktopBackAndForth; } Settings; diff --git a/src/winmenu.c b/src/winmenu.c index ee7fbe9d..e236602c 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -46,7 +46,9 @@ Menu *CreateWindowMenu(ClientNode *np) if(!(np->state.status & STAT_WMDIALOG)) { AddWindowMenuItem(menu, _("Close"), MA_CLOSE, np, 0); - AddWindowMenuItem(menu, _("Kill"), MA_KILL, np, 0); + if (settings.showKillMenuItem){ + AddWindowMenuItem(menu, _("Kill"), MA_KILL, np, 0); + } AddWindowMenuItem(menu, NULL, MA_NONE, np, 0); } From f75b5b3b9de35be204a2ba92ee96714fc12d8d99 Mon Sep 17 00:00:00 2001 From: Mike Hewitt Date: Thu, 15 Sep 2022 12:28:45 -0400 Subject: [PATCH 2/2] responding to code review comments --- jwm.1.in | 4 ++-- src/border.c | 17 +++++++++-------- src/client.c | 4 ++-- src/client.h | 2 +- src/group.c | 20 ++++++++++---------- src/hint.c | 12 ++++++------ src/parse.c | 17 ++++++++--------- src/settings.c | 8 ++++++-- src/settings.h | 8 ++------ 9 files changed, 46 insertions(+), 46 deletions(-) diff --git a/jwm.1.in b/jwm.1.in index 1c4f650c..544b5fa7 100644 --- a/jwm.1.in +++ b/jwm.1.in @@ -1082,7 +1082,7 @@ The window decorations to use. Valid options are \fBflat\fP and \fBmotif\fP. \fBflat\fP is the default. .RE .P -.B machinename +.B showclient .RS Include the X client machine name (WM_CLIENT_MACHINE) in the window title. Valid options are \fBtrue\fP and \fBfalse\fP. \fBfalse\fP is the default. @@ -1291,7 +1291,7 @@ Possible values are \fBdesktop\fP and \fBall\fP. The default is \fBdesktop\fP. .RE .P -.B killmenu +.B showkill .RS Determines if the \fBKill\fP popup menu item is shown on task bars and window title bars. Possible values are \fBtrue\fP and \fBfalse\fP. The default diff --git a/src/border.c b/src/border.c index 5c5759ae..9487cc67 100644 --- a/src/border.c +++ b/src/border.c @@ -451,15 +451,16 @@ void DrawBorderHelper(const ClientNode *np) if(np->name && np->name[0] && point.x < point.y) { unsigned titleWidth = point.y - point.x; const int sheight = GetStringHeight(FONT_BORDER); - const int buffSize = (MAX_TITLE_LENGTH+1)*sizeof(char); - char *titleBuffer = calloc(MAX_TITLE_LENGTH+1,sizeof(char)); - titleBuffer = memset(titleBuffer,'\0',buffSize); - if (settings.showMachineName){ + char *titleBuffer; + if (settings.showClientName && np->clientName && np->clientName[0]){ + /* Space for 2 delimiters, space, terminator, and strings */ + const size_t buffSize = strlen(np->name) + strlen(np->clientName) + 4; + titleBuffer = Allocate(buffSize); sprintf(titleBuffer,"%s %c%s%c",np->name, - settings.machineNameDelimiters[0],np->machineName, - settings.machineNameDelimiters[1]); + settings.clientNameDelimiters[0],np->clientName, + settings.clientNameDelimiters[1]); } else { - sprintf(titleBuffer,"%s",np->name); + titleBuffer = CopyString(np->name); } const int textWidth = GetStringWidth(FONT_BORDER,titleBuffer); unsigned titlex, titley; @@ -485,7 +486,7 @@ void DrawBorderHelper(const ClientNode *np) } RenderString(canvas, FONT_BORDER, borderTextColor, titlex, titley, titleWidth, titleBuffer); - free(titleBuffer); + Release(titleBuffer); } } diff --git a/src/client.c b/src/client.c index a6004896..4856fd43 100644 --- a/src/client.c +++ b/src/client.c @@ -1260,8 +1260,8 @@ void RemoveClient(ClientNode *np) if(np->className) { JXFree(np->className); } - if(np->machineName) { - Release(np->machineName); + if(np->clientName) { + Release(np->clientName); } RemoveClientFromTaskBar(np); diff --git a/src/client.h b/src/client.h index b13d0fc7..6be53537 100644 --- a/src/client.h +++ b/src/client.h @@ -147,7 +147,7 @@ typedef struct ClientNode { char *name; /**< Name of this window for display. */ char *instanceName; /**< Name of this window for properties. */ char *className; /**< Name of the window class. */ - char *machineName; /**< Name of the machine. */ + char *clientName; /**< Name of the client machine. */ ClientState state; /**< Window state. */ diff --git a/src/group.c b/src/group.c index e2be5481..f29acefc 100644 --- a/src/group.c +++ b/src/group.c @@ -21,7 +21,7 @@ typedef unsigned int MatchType; #define MATCH_NAME 0 /**< Match the window name. */ #define MATCH_CLASS 1 /**< Match the window class. */ #define MATCH_TYPE 2 /**< Match the window type. */ -#define MATCH_MACHINE 3 /**< Match the window machine. */ +#define MATCH_MACHINE 3 /**< Match the window client machine name. */ #define MATCH_TITLE 4 /**< Match the window title. */ /** List of match patterns for a group. */ @@ -152,7 +152,7 @@ void AddGroupType(GroupType *gp, const char *pattern) } } -/** Add a window machine to a group. */ +/** Add a window client machine to a group. */ void AddGroupMachine(GroupType *gp, const char *pattern) { Assert(gp); @@ -237,12 +237,12 @@ void ApplyGroups(ClientNode *np) char hasName; char hasTitle; char hasType; - char hasMachine; + char hasClient; char matchesClass; char matchesName; char matchesTitle; char matchesType; - char matchesMachine; + char matchesClient; static const StringMappingType windowTypeMapping[] = { { "desktop", WINDOW_TYPE_DESKTOP }, @@ -262,12 +262,12 @@ void ApplyGroups(ClientNode *np) hasName = 0; hasType = 0; hasTitle = 0; - hasMachine = 0; + hasClient = 0; matchesClass = 0; matchesName = 0; matchesTitle = 0; matchesType = 0; - matchesMachine = 0; + matchesClient = 0; for(lp = gp->patterns; lp; lp = lp->next) { if(lp->match == MATCH_CLASS) { if(Match(lp->pattern, np->className)) { @@ -291,10 +291,10 @@ void ApplyGroups(ClientNode *np) } hasType = 1; } else if(lp->match == MATCH_MACHINE) { - if(Match(lp->pattern, np->machineName)) { - matchesMachine = 1; + if(Match(lp->pattern, np->clientName)) { + matchesClient = 1; } - hasMachine = 1; + hasClient = 1; } else { Debug("invalid match in ApplyGroups: %d", lp->match); } @@ -303,7 +303,7 @@ void ApplyGroups(ClientNode *np) && hasClass == matchesClass && hasTitle == matchesTitle && hasType == matchesType - && hasMachine == matchesMachine) { + && hasClient == matchesClient) { ApplyGroup(gp, np); } } diff --git a/src/hint.c b/src/hint.c index ff00eff0..dc9c6d0a 100644 --- a/src/hint.c +++ b/src/hint.c @@ -788,26 +788,26 @@ void ReadWMName(ClientNode *np) } -/** Read the machine for a client. */ +/** Read the machine name of a client. */ void ReadWMMachine(ClientNode *np) { XTextProperty tprop; char **tlist; int tcount; - if(np->machineName) { - Release(np->machineName); + if(np->clientName) { + Release(np->clientName); } XGetWMClientMachine(display, np->window, &tprop); if(XmbTextPropertyToTextList(display, &tprop, &tlist, &tcount) == Success && tcount > 0) { const size_t len = strlen(tlist[0]) + 1; - np->machineName = Allocate(len); - memcpy(np->machineName, tlist[0], len); + np->clientName = Allocate(len); + memcpy(np->clientName, tlist[0], len); XFreeStringList(tlist); } else { - np->machineName = NULL; + np->clientName = NULL; } } diff --git a/src/parse.c b/src/parse.c index c66e3741..0c70397c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -160,9 +160,9 @@ static const char *DYNAMIC_ATTRIBUTE = "dynamic"; static const char *SPACING_ATTRIBUTE = "spacing"; static const char *TIMEOUT_ATTRIBUTE = "timeout"; static const char *POPUP_ATTRIBUTE = "popup"; -static const char *MACHINENAME_ATTRIBUTE = "machinename"; -static const char *MN_DELIMITERS_ATTRIBUTE = "delimiters"; -static const char *KILL_MENU_ATTRIBUTE = "killmenu"; +static const char *CLIENTNAME_ATTRIBUTE = "showclient"; +static const char *CN_DELIMITERS_ATTRIBUTE = "delimiters"; +static const char *KILL_MENU_ATTRIBUTE = "showkill"; static const char *FALSE_VALUE = "false"; static const char *TRUE_VALUE = "true"; @@ -1002,16 +1002,15 @@ void ParseWindowStyle(const TokenNode *tp) const TokenNode *np; const char *temp; - temp = FindAttribute(tp->attributes, MACHINENAME_ATTRIBUTE); + temp = FindAttribute(tp->attributes, CLIENTNAME_ATTRIBUTE); if(temp){ - settings.showMachineName = !strcmp(temp,TRUE_VALUE); + settings.showClientName = !strcmp(temp,TRUE_VALUE); } - temp = FindAttribute(tp->attributes, MN_DELIMITERS_ATTRIBUTE); + temp = FindAttribute(tp->attributes, CN_DELIMITERS_ATTRIBUTE); if(temp && strlen(temp)>=2) { - char *delims = calloc(strlen(temp)+1,sizeof(char)); - sprintf(delims,"%s",temp); - settings.machineNameDelimiters = delims; + memcpy(settings.clientNameDelimiters, temp, + sizeof(settings.clientNameDelimiters)); } ParseDecorations(tp, &settings.windowDecorations); diff --git a/src/settings.c b/src/settings.c index ddaf5340..e9956772 100644 --- a/src/settings.c +++ b/src/settings.c @@ -22,6 +22,9 @@ static const MouseContextType DEFAULT_TITLE_BAR_LAYOUT[TBC_COUNT + 1] = { MC_NONE }; +/** Default characters for client machine name delimiters. */ +static const char DEFAULT_CLIENT_NAME_DELIMITERS[2] = {'(',')'}; + static void FixRange(unsigned int *value, unsigned int min_value, unsigned int max_value, @@ -61,8 +64,9 @@ void InitializeSettings(void) settings.groupTasks = 0; settings.listAllTasks = 0; settings.dockSpacing = 0; - settings.showMachineName = 0; - settings.machineNameDelimiters = DEFAULT_MACHINE_NAME_DELIMITERS; + settings.showClientName = 0; + memcpy(settings.clientNameDelimiters, DEFAULT_CLIENT_NAME_DELIMITERS, + sizeof(settings.clientNameDelimiters)); settings.showKillMenuItem = 1; memcpy(settings.titleBarLayout, DEFAULT_TITLE_BAR_LAYOUT, sizeof(settings.titleBarLayout)); diff --git a/src/settings.h b/src/settings.h index 2c25b8f0..4a803729 100644 --- a/src/settings.h +++ b/src/settings.h @@ -88,10 +88,6 @@ typedef unsigned char DesktopBackAndForthType; * For now, we allow each component to be used twice. */ #define TBC_COUNT 9 -/** Maximum number of characters in window title - * and default characters for machine name delimiters. */ -#define MAX_TITLE_LENGTH 512 -#define DEFAULT_MACHINE_NAME_DELIMITERS "()" /** Settings. */ typedef struct { @@ -127,8 +123,8 @@ typedef struct { MouseContextType titleBarLayout[TBC_COUNT + 1]; char groupTasks; char listAllTasks; - char showMachineName; - char *machineNameDelimiters; + char showClientName; + char clientNameDelimiters[2]; char showKillMenuItem; DesktopBackAndForthType desktopBackAndForth; } Settings;