diff --git a/src/border.c b/src/border.c index 71a7e47e..256ba316 100644 --- a/src/border.c +++ b/src/border.c @@ -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, @@ -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); @@ -960,7 +962,7 @@ 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(); @@ -968,7 +970,9 @@ void DrawCloseButton(unsigned xoffset, unsigned yoffset, 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; } @@ -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]; @@ -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; } @@ -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; @@ -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; } @@ -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; } @@ -1150,7 +1160,7 @@ 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; @@ -1158,7 +1168,14 @@ void DrawIconButton(const ClientNode *np, int x, int y, 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, diff --git a/src/border.h b/src/border.h index 75c8084d..3684dd60 100644 --- a/src/border.h +++ b/src/border.h @@ -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); diff --git a/src/lex.c b/src/lex.c index 27e908a9..4249cea6 100644 --- a/src/lex.c +++ b/src/lex.c @@ -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); diff --git a/src/lex.h b/src/lex.h index 10e2eb34..90579419 100644 --- a/src/lex.h +++ b/src/lex.h @@ -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, diff --git a/src/parse.c b/src/parse.c index 1ba414b7..b6beb34d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -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;