Skip to content

Commit

Permalink
Add active window variants of ButtonClose et al.
Browse files Browse the repository at this point in the history
Implements 'Focus' variants of ButtonClose & others for setting active window icons.
  • Loading branch information
Taylor-Finch authored Sep 1, 2024
1 parent a4318c5 commit 7fcea14
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 102 deletions.
57 changes: 37 additions & 20 deletions src/border.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ static char DrawBorderIcon(BorderIconType t,
unsigned xoffset, unsigned yoffset,
Pixmap canvas, long fg);
static void DrawIconButton(const ClientNode *np, int x, int y,
Pixmap canvas, GC gc, long fg);
Pixmap canvas, GC gc, long fg, char active);
static void DrawCloseButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg);
Pixmap canvas, GC gc, long fg, char active);
static void DrawMaxIButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg);
Pixmap canvas, GC gc, long fg, char active);
static void DrawMaxAButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg);
Pixmap canvas, GC gc, long fg, char active);
static void DrawMinButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg);
Pixmap canvas, GC gc, long fg, char active);

#ifdef USE_SHAPE
static void FillRoundedRectangle(Drawable d, GC gc, int x, int y,
Expand Down Expand Up @@ -786,23 +786,25 @@ void DrawBorderHandles(const ClientNode *np, Pixmap canvas, GC gc)
void DrawBorderButton(const ClientNode *np, MouseContextType context,
int x, int y, Pixmap canvas, GC gc, long fg)
{
const char isActive = (np->state.status & STAT_ACTIVE)
&& IsClientOnCurrentDesktop(np);
JXSetForeground(display, gc, fg);
switch(context) {
case MC_CLOSE:
DrawCloseButton(x, y, canvas, gc, fg);
DrawCloseButton(x, y, canvas, gc, fg, isActive);
break;
case MC_MINIMIZE:
DrawMinButton(x, y, canvas, gc, fg);
DrawMinButton(x, y, canvas, gc, fg, isActive);
break;
case MC_MAXIMIZE:
if(np->state.maxFlags) {
DrawMaxAButton(x, y, canvas, gc, fg);
DrawMaxAButton(x, y, canvas, gc, fg, isActive);
} else {
DrawMaxIButton(x, y, canvas, gc, fg);
DrawMaxIButton(x, y, canvas, gc, fg, isActive);
}
break;
case MC_ICON:
DrawIconButton(np, x, y, canvas, gc, fg);
DrawIconButton(np, x, y, canvas, gc, fg, isActive);
break;
default:
Assert(0);
Expand Down Expand Up @@ -960,15 +962,17 @@ char DrawBorderIcon(BorderIconType t,

/** Draw a close button. */
void DrawCloseButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg)
Pixmap canvas, GC gc, long fg, char active)
{
XSegment segments[2];
const unsigned titleHeight = GetTitleHeight();
unsigned size;
unsigned x1, y1;
unsigned x2, y2;

if(DrawBorderIcon(BI_CLOSE, xoffset, yoffset, canvas, fg)) {
if(active && DrawBorderIcon(BI_CLOSE_FOCUS, xoffset, yoffset, canvas, fg)) {
return;
} else if(DrawBorderIcon(BI_CLOSE, xoffset, yoffset, canvas, fg)) {
return;
}

Expand Down Expand Up @@ -998,7 +1002,7 @@ void DrawCloseButton(unsigned xoffset, unsigned yoffset,

/** Draw an inactive maximize button. */
void DrawMaxIButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg)
Pixmap canvas, GC gc, long fg, char active)
{

XSegment segments[5];
Expand All @@ -1007,7 +1011,9 @@ void DrawMaxIButton(unsigned xoffset, unsigned yoffset,
unsigned int x1, y1;
unsigned int x2, y2;

if(DrawBorderIcon(BI_MAX, xoffset, yoffset, canvas, fg)) {
if(active && DrawBorderIcon(BI_MAX_FOCUS, xoffset, yoffset, canvas, fg)) {
return;
} else if(DrawBorderIcon(BI_MAX, xoffset, yoffset, canvas, fg)) {
return;
}

Expand Down Expand Up @@ -1052,7 +1058,7 @@ void DrawMaxIButton(unsigned xoffset, unsigned yoffset,

/** Draw an active maximize button. */
void DrawMaxAButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg)
Pixmap canvas, GC gc, long fg, char active)
{
XSegment segments[8];
unsigned titleHeight;
Expand All @@ -1061,7 +1067,9 @@ void DrawMaxAButton(unsigned xoffset, unsigned yoffset,
unsigned x2, y2;
unsigned x3, y3;

if(DrawBorderIcon(BI_MAX_ACTIVE, xoffset, yoffset, canvas, fg)) {
if(active && DrawBorderIcon(BI_MAX_ACTIVE_FOCUS, xoffset, yoffset, canvas, fg)) {
return;
} else if(DrawBorderIcon(BI_MAX_ACTIVE, xoffset, yoffset, canvas, fg)) {
return;
}

Expand Down Expand Up @@ -1123,14 +1131,16 @@ void DrawMaxAButton(unsigned xoffset, unsigned yoffset,

/** Draw a minimize button. */
void DrawMinButton(unsigned xoffset, unsigned yoffset,
Pixmap canvas, GC gc, long fg)
Pixmap canvas, GC gc, long fg, char active)
{
unsigned titleHeight;
unsigned size;
unsigned x1, y1;
unsigned x2, y2;

if(DrawBorderIcon(BI_MIN, xoffset, yoffset, canvas, fg)) {
if(active && DrawBorderIcon(BI_MIN_FOCUS, xoffset, yoffset, canvas, fg)) {
return;
} else if(DrawBorderIcon(BI_MIN, xoffset, yoffset, canvas, fg)) {
return;
}

Expand All @@ -1150,15 +1160,22 @@ void DrawMinButton(unsigned xoffset, unsigned yoffset,

/* Draw the title icon. */
void DrawIconButton(const ClientNode *np, int x, int y,
Pixmap canvas, GC gc, long fg)
Pixmap canvas, GC gc, long fg, char active)
{
#ifdef USE_ICONS
const char hasIcon = np->icon ? 1 : 0;
const int titleHeight = GetTitleHeight();
const int iconSize = hasIcon ? GetBorderIconSize() : Max((int)titleHeight - 2, 0);
const int iconXOffset = (titleHeight - iconSize) / 2;
const int iconYOffset = hasIcon ? iconXOffset : iconXOffset + 1;
IconNode *icon = hasIcon ? np->icon : buttonIcons[BI_MENU];
IconNode *icon;
if(hasIcon) {
icon = np->icon;
} else if(active && (buttonIcons[BI_MENU_FOCUS] != NULL)) {
icon = buttonIcons[BI_MENU_FOCUS];
} else {
icon = buttonIcons[BI_MENU];
}
PutIcon(icon, canvas, fg,
x + iconXOffset,
y + iconYOffset,
Expand Down
17 changes: 11 additions & 6 deletions src/border.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ struct ClientState;

/** Border icon types. */
typedef unsigned char BorderIconType;
#define BI_CLOSE 0
#define BI_MAX 1
#define BI_MAX_ACTIVE 2
#define BI_MENU 3
#define BI_MIN 4
#define BI_COUNT 5
#define BI_CLOSE 0
#define BI_CLOSE_FOCUS 1
#define BI_MAX 2
#define BI_MAX_FOCUS 3
#define BI_MAX_ACTIVE 4
#define BI_MAX_ACTIVE_FOCUS 5
#define BI_MENU 6
#define BI_MENU_FOCUS 7
#define BI_MIN 8
#define BI_MIN_FOCUS 9
#define BI_COUNT 10

/*@{*/
void InitializeBorders(void);
Expand Down
157 changes: 81 additions & 76 deletions src/lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,82 +19,87 @@ static const int BLOCK_SIZE = 16;
* These must be sorted.
*/
static const StringMappingType TOKEN_MAP[] = {
{ "Active", TOK_ACTIVE },
{ "Background", TOK_BACKGROUND },
{ "Button", TOK_BUTTON },
{ "ButtonClose", TOK_BUTTONCLOSE },
{ "ButtonMax", TOK_BUTTONMAX },
{ "ButtonMaxActive", TOK_BUTTONMAXACTIVE },
{ "ButtonMenu", TOK_BUTTONMENU },
{ "ButtonMin", TOK_BUTTONMIN },
{ "Class", TOK_CLASS },
{ "Clock", TOK_CLOCK },
{ "ClockStyle", TOK_CLOCKSTYLE },
{ "Close", TOK_CLOSE },
{ "Corner", TOK_CORNER },
{ "DefaultIcon", TOK_DEFAULTICON },
{ "Desktop", TOK_DESKTOP },
{ "Desktops", TOK_DESKTOPS },
{ "Dock", TOK_DOCK },
{ "DoubleClickDelta", TOK_DOUBLECLICKDELTA },
{ "DoubleClickSpeed", TOK_DOUBLECLICKSPEED },
{ "Dynamic", TOK_DYNAMIC },
{ "Exit", TOK_EXIT },
{ "FocusModel", TOK_FOCUSMODEL },
{ "Font", TOK_FONT },
{ "Foreground", TOK_FOREGROUND },
{ "Group", TOK_GROUP },
{ "Height", TOK_HEIGHT },
{ "IconPath", TOK_ICONPATH },
{ "Include", TOK_INCLUDE },
{ "JWM", TOK_JWM },
{ "Key", TOK_KEY },
{ "Kill", TOK_KILL },
{ "Layer", TOK_LAYER },
{ "Machine", TOK_MACHINE },
{ "Maximize", TOK_MAXIMIZE },
{ "Menu", TOK_MENU },
{ "MenuStyle", TOK_MENUSTYLE },
{ "Minimize", TOK_MINIMIZE },
{ "Minimized", TOK_MINIMIZED },
{ "Mouse", TOK_MOUSE },
{ "Move", TOK_MOVE },
{ "MoveMode", TOK_MOVEMODE },
{ "Name", TOK_NAME },
{ "Opacity", TOK_OPACITY },
{ "Option", TOK_OPTION },
{ "Outline", TOK_OUTLINE },
{ "Pager", TOK_PAGER },
{ "PagerStyle", TOK_PAGERSTYLE },
{ "Popup", TOK_POPUP },
{ "PopupStyle", TOK_POPUPSTYLE },
{ "Program", TOK_PROGRAM },
{ "Resize", TOK_RESIZE },
{ "ResizeMode", TOK_RESIZEMODE },
{ "Restart", TOK_RESTART },
{ "RestartCommand", TOK_RESTARTCOMMAND },
{ "RootMenu", TOK_ROOTMENU },
{ "SendTo", TOK_SENDTO },
{ "Separator", TOK_SEPARATOR },
{ "Shade", TOK_SHADE },
{ "ShutdownCommand", TOK_SHUTDOWNCOMMAND },
{ "SnapMode", TOK_SNAPMODE },
{ "Spacer", TOK_SPACER },
{ "StartupCommand", TOK_STARTUPCOMMAND },
{ "Stick", TOK_STICK },
{ "Swallow", TOK_SWALLOW },
{ "TaskList", TOK_TASKLIST },
{ "TaskListStyle", TOK_TASKLISTSTYLE },
{ "Text", TOK_TEXT },
{ "Title", TOK_TITLE },
{ "TitleButtonOrder", TOK_TITLEBUTTONORDER },
{ "Tray", TOK_TRAY },
{ "TrayButton", TOK_TRAYBUTTON },
{ "TrayButtonStyle", TOK_TRAYBUTTONSTYLE },
{ "TrayStyle", TOK_TRAYSTYLE },
{ "Type", TOK_TYPE },
{ "Width", TOK_WIDTH },
{ "WindowStyle", TOK_WINDOWSTYLE }
{ "Active", TOK_ACTIVE },
{ "Background", TOK_BACKGROUND },
{ "Button", TOK_BUTTON },
{ "ButtonClose", TOK_BUTTONCLOSE },
{ "ButtonCloseFocus", TOK_BUTTONCLOSEFOCUS },
{ "ButtonMax", TOK_BUTTONMAX },
{ "ButtonMaxActive", TOK_BUTTONMAXACTIVE },
{ "ButtonMaxActiveFocus", TOK_BUTTONMAXACTIVEFOCUS },
{ "ButtonMaxFocus", TOK_BUTTONMAXFOCUS },
{ "ButtonMenu", TOK_BUTTONMENU },
{ "ButtonMenuFocus", TOK_BUTTONMENUFOCUS },
{ "ButtonMin", TOK_BUTTONMIN },
{ "ButtonMinFocus", TOK_BUTTONMINFOCUS },
{ "Class", TOK_CLASS },
{ "Clock", TOK_CLOCK },
{ "ClockStyle", TOK_CLOCKSTYLE },
{ "Close", TOK_CLOSE },
{ "Corner", TOK_CORNER },
{ "DefaultIcon", TOK_DEFAULTICON },
{ "Desktop", TOK_DESKTOP },
{ "Desktops", TOK_DESKTOPS },
{ "Dock", TOK_DOCK },
{ "DoubleClickDelta", TOK_DOUBLECLICKDELTA },
{ "DoubleClickSpeed", TOK_DOUBLECLICKSPEED },
{ "Dynamic", TOK_DYNAMIC },
{ "Exit", TOK_EXIT },
{ "FocusModel", TOK_FOCUSMODEL },
{ "Font", TOK_FONT },
{ "Foreground", TOK_FOREGROUND },
{ "Group", TOK_GROUP },
{ "Height", TOK_HEIGHT },
{ "IconPath", TOK_ICONPATH },
{ "Include", TOK_INCLUDE },
{ "JWM", TOK_JWM },
{ "Key", TOK_KEY },
{ "Kill", TOK_KILL },
{ "Layer", TOK_LAYER },
{ "Machine", TOK_MACHINE },
{ "Maximize", TOK_MAXIMIZE },
{ "Menu", TOK_MENU },
{ "MenuStyle", TOK_MENUSTYLE },
{ "Minimize", TOK_MINIMIZE },
{ "Minimized", TOK_MINIMIZED },
{ "Mouse", TOK_MOUSE },
{ "Move", TOK_MOVE },
{ "MoveMode", TOK_MOVEMODE },
{ "Name", TOK_NAME },
{ "Opacity", TOK_OPACITY },
{ "Option", TOK_OPTION },
{ "Outline", TOK_OUTLINE },
{ "Pager", TOK_PAGER },
{ "PagerStyle", TOK_PAGERSTYLE },
{ "Popup", TOK_POPUP },
{ "PopupStyle", TOK_POPUPSTYLE },
{ "Program", TOK_PROGRAM },
{ "Resize", TOK_RESIZE },
{ "ResizeMode", TOK_RESIZEMODE },
{ "Restart", TOK_RESTART },
{ "RestartCommand", TOK_RESTARTCOMMAND },
{ "RootMenu", TOK_ROOTMENU },
{ "SendTo", TOK_SENDTO },
{ "Separator", TOK_SEPARATOR },
{ "Shade", TOK_SHADE },
{ "ShutdownCommand", TOK_SHUTDOWNCOMMAND },
{ "SnapMode", TOK_SNAPMODE },
{ "Spacer", TOK_SPACER },
{ "StartupCommand", TOK_STARTUPCOMMAND },
{ "Stick", TOK_STICK },
{ "Swallow", TOK_SWALLOW },
{ "TaskList", TOK_TASKLIST },
{ "TaskListStyle", TOK_TASKLISTSTYLE },
{ "Text", TOK_TEXT },
{ "Title", TOK_TITLE },
{ "TitleButtonOrder", TOK_TITLEBUTTONORDER },
{ "Tray", TOK_TRAY },
{ "TrayButton", TOK_TRAYBUTTON },
{ "TrayButtonStyle", TOK_TRAYBUTTONSTYLE },
{ "TrayStyle", TOK_TRAYSTYLE },
{ "Type", TOK_TYPE },
{ "Width", TOK_WIDTH },
{ "WindowStyle", TOK_WINDOWSTYLE }
};
static const unsigned int TOKEN_MAP_COUNT = ARRAY_LENGTH(TOKEN_MAP);

Expand Down
5 changes: 5 additions & 0 deletions src/lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ typedef enum {
TOK_BACKGROUND,
TOK_BUTTON,
TOK_BUTTONCLOSE,
TOK_BUTTONCLOSEFOCUS,
TOK_BUTTONMAX,
TOK_BUTTONMAXACTIVE,
TOK_BUTTONMAXACTIVEFOCUS,
TOK_BUTTONMAXFOCUS,
TOK_BUTTONMENU,
TOK_BUTTONMENUFOCUS,
TOK_BUTTONMIN,
TOK_BUTTONMINFOCUS,
TOK_CLASS,
TOK_CLOCK,
TOK_CLOCKSTYLE,
Expand Down
15 changes: 15 additions & 0 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,18 +430,33 @@ void Parse(const TokenNode *start, int depth)
case TOK_BUTTONCLOSE:
SetBorderIcon(BI_CLOSE, tp->value);
break;
case TOK_BUTTONCLOSEFOCUS:
SetBorderIcon(BI_CLOSE_FOCUS, tp->value);
break;
case TOK_BUTTONMAX:
SetBorderIcon(BI_MAX, tp->value);
break;
case TOK_BUTTONMAXACTIVE:
SetBorderIcon(BI_MAX_ACTIVE, tp->value);
break;
case TOK_BUTTONMAXACTIVEFOCUS:
SetBorderIcon(BI_MAX_ACTIVE_FOCUS, tp->value);
break;
case TOK_BUTTONMAXFOCUS:
SetBorderIcon(BI_MAX_FOCUS, tp->value);
break;
case TOK_BUTTONMIN:
SetBorderIcon(BI_MIN, tp->value);
break;
case TOK_BUTTONMINFOCUS:
SetBorderIcon(BI_MIN_FOCUS, tp->value);
break;
case TOK_BUTTONMENU:
SetBorderIcon(BI_MENU, tp->value);
break;
case TOK_BUTTONMENUFOCUS:
SetBorderIcon(BI_MENU_FOCUS, tp->value);
break;
case TOK_DEFAULTICON:
SetDefaultIcon(tp->value);
break;
Expand Down

0 comments on commit 7fcea14

Please sign in to comment.