diff --git a/src/client.c b/src/client.c
index 5611c92..ad7f867 100644
--- a/src/client.c
+++ b/src/client.c
@@ -20,6 +20,7 @@ along with this program. If not, see .
#include "client.h"
#include "util.h"
#include "wm.h"
+#include
#include
#include
#include
@@ -162,6 +163,7 @@ void wm_client_hide(Wm *wm, Client *c)
return;
c->hidden = true;
+ XUnmapWindow(wm->display, c->frame);
XUnmapWindow(wm->display, c->window);
}
@@ -173,6 +175,7 @@ void wm_client_show(Wm *wm, Client *c)
return;
c->hidden = false;
+ XMapWindow(wm->display, c->frame);
XMapWindow(wm->display, c->window);
}
@@ -195,6 +198,7 @@ void wm_client_focus(Wm *wm, Client *c)
TreeNode *node = wm_treenode_ptr_find_client_node(c->ws->tree, c);
c->ws->focused_node = node;
wm_monitor_clients_border(wm, c->m);
+ wm_monitor_draw_all_clients_frame(wm, c->m);
}
void wm_client_focus_dir(Wm *wm, Client *c, int dir)
@@ -270,6 +274,8 @@ void wm_client_kill(Wm *wm, Client *c)
if (XSendEvent(wm->display, c->window, false, NoEventMask, &event) != Success)
XKillClient(wm->display, c->window);
+ XDestroyWindow(wm->display, c->frame);
+
TreeNode* parent = wm_treenode_remove_client(wm, c->ws->tree, c);
wm_client_free(wm, c);
@@ -470,3 +476,38 @@ bool wm_client_is_focused(Wm *wm, Client *c)
return false;
}
+
+void wm_client_draw_frame(Wm *wm, Client *c)
+{
+ if (!wm->config.show_titlebar) return;
+ DEBUG_PRINT("%s\n", __func__);
+
+
+ int screen = DefaultScreen(wm->display);
+ Visual *visual = DefaultVisual(wm->display, screen);
+ Colormap cmap = DefaultColormap(wm->display, screen);
+
+ XftDraw *draw = XftDrawCreate(wm->display, c->frame, visual, cmap);
+
+ XftDrawRect(draw, (wm_client_is_focused(wm, c) ? &wm->titlebar_focused_color :
+ &wm->titlebar_color), 0, 0, c->w, c->h);
+
+ XftDrawStringUtf8(draw, &wm->titlebar_text_color, wm->titlebar_font,
+ 20, 30, (void*)c->name, strlen(c->name));
+ XftDrawDestroy(draw);
+}
+
+void wm_monitor_draw_all_clients_frame(Wm* wm, Monitor *m)
+{
+ DEBUG_PRINT("%s\n", __func__);
+ NodeArray *clients = wm_treenode_find_client_nodes(m->workspaces[m->selected_ws].tree);
+ if (clients->size == 0)
+ return;
+
+ for (size_t i = 0; i < clients->size; i++) {
+ Client *client = ((TreeNode*)clients->nodes[i])->client;
+ wm_client_draw_frame(wm, client);
+ }
+
+ wm_nodearray_free(clients);
+}
diff --git a/src/client.h b/src/client.h
index c11da49..6ecad1a 100644
--- a/src/client.h
+++ b/src/client.h
@@ -38,6 +38,7 @@ struct Client {
bool hidden;
Monitor *m;
Window window;
+ Window frame;
Client *prev;
Client *next;
char *name;
@@ -72,6 +73,7 @@ void wm_client_border_focused(Wm* wm, Client *c);
void wm_monitor_clients_border(Wm* wm, Monitor *m);
bool wm_client_is_focused(Wm* wm, Client *c);
-
+void wm_client_draw_frame(Wm *wm, Client *c);
+void wm_monitor_draw_all_clients_frame(Wm* wm, Monitor *m);
#endif
diff --git a/src/config.c b/src/config.c
index 05a8992..0a4dc8f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -57,10 +57,15 @@ static const KeybindFunctionCommand __wm_keybind_commands[] = {
void wm_cfg_init_def(Config *config)
{
config->ms_p = 0.5;
- strncpy(config->border_col, "#222222", CONFIG_COLOR_MAX);
- strncpy(config->focused_border_col, "#444444", CONFIG_COLOR_MAX);
+ strcpy(config->border_col, "#222222");
+ strcpy(config->focused_border_col, "#444444");
config->border_width = 2;
config->focus_on_motion = true;
+ config->show_titlebar = true;
+ strcpy(config->titlebar_color, "#000000");
+ strcpy(config->titlebar_focused_color, "#4169e1");
+ strcpy(config->titlebar_font, "monospace:size=18:antialias=true");
+ strcpy(config->titlebar_text_color, "#ffffff");
wm_keybinds_init_def(config);
@@ -237,6 +242,26 @@ void wm_configfile_init(ConfigFile *config, const char *filename)
(ConfigCommand) {.string = "focus_on_motion", .arg_count = 1,
.cfg_var_offset[0] = offsetof(Config, focus_on_motion),
.argc = 0, .arg_type = TYPE_BOOL},
+
+ (ConfigCommand) {.string = "show_titlebar", .arg_count = 1,
+ .cfg_var_offset[0] = offsetof(Config, show_titlebar),
+ .argc = 0, .arg_type = TYPE_BOOL},
+
+ (ConfigCommand) {.string = "titlebar_color", .arg_count = 1,
+ .cfg_var_offset[0] = offsetof(Config, titlebar_color),
+ .argc = 0, .arg_type = TYPE_STRING},
+
+ (ConfigCommand) {.string = "titlebar_focused_color", .arg_count = 1,
+ .cfg_var_offset[0] = offsetof(Config, titlebar_focused_color),
+ .argc = 0, .arg_type = TYPE_STRING},
+
+ (ConfigCommand) {.string = "titlebar_font", .arg_count = 1,
+ .cfg_var_offset[0] = offsetof(Config, titlebar_font),
+ .argc = 0, .arg_type = TYPE_STRING},
+
+ (ConfigCommand) {.string = "titlebar_text_color", .arg_count = 1,
+ .cfg_var_offset[0] = offsetof(Config, titlebar_text_color),
+ .argc = 0, .arg_type = TYPE_STRING},
};
config->command_count = sizeof(commands) / sizeof (commands[0]);
@@ -605,6 +630,7 @@ int wm_string_to_direction(const char *str)
KeybindFunction wm_str_to_keybindfunction(const char* str)
{
DEBUG_PRINT("%s %s\n", __func__, str);
+
char lower[CONFIG_ARGLEN_MAX];
strncpy(lower, str, CONFIG_ARGLEN_MAX);
diff --git a/src/config.h b/src/config.h
index f568587..04ce792 100644
--- a/src/config.h
+++ b/src/config.h
@@ -87,6 +87,11 @@ typedef struct {
Keybind *keybinds;
int kb_count;
bool focus_on_motion;
+ bool show_titlebar;
+ char titlebar_color[CONFIG_COLOR_MAX];
+ char titlebar_focused_color[CONFIG_COLOR_MAX];
+ char titlebar_font[CONFIG_ARGLEN_MAX];
+ char titlebar_text_color[CONFIG_COLOR_MAX];
char log_path[PATH_MAX];
} Config;
diff --git a/src/handler.c b/src/handler.c
index aaea23c..47490c9 100644
--- a/src/handler.c
+++ b/src/handler.c
@@ -94,8 +94,22 @@ void wm_maprequest_handler(Wm *wm, XMapRequestEvent e)
DEBUG_PRINT("%s: client not found, creating client\n", __func__)
+ Window frame = XCreateSimpleWindow(wm->display, wm->root.window, 0, 0,
+ 10, 10, 0, 0, 0);
+
+ XReparentWindow(wm->display, e.window, frame, 0, 0);
+
+ XTextProperty xtp;
+ XGetWMName(wm->display, e.window, &xtp);
+ XSetWMName(wm->display, frame, &xtp);
+ XFree(xtp.value);
+
+ XMapWindow(wm->display, frame);
+ XMapWindow(wm->display, e.window);
+
c = wm_client_create(wm, e.window);
RETURN_IF_NULL(c);
+ c->frame = frame;
wm_ws_tree_insert_client(wm, c->ws, c);
diff --git a/src/wm.c b/src/wm.c
index 6776989..5b5535b 100644
--- a/src/wm.c
+++ b/src/wm.c
@@ -31,6 +31,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include "wm.h"
#include "config.h"
#include "handler.h"
@@ -317,11 +318,21 @@ void wm_layout(Wm *wm, Monitor *m)
unsigned int value_mask = CWX | CWY | CWWidth | CWHeight;
XWindowChanges xwc = wm_client_to_xwchanges((client));
- XConfigureWindow(wm->display, client->window, value_mask, &xwc);
- wm_client_show(wm, client);
- }
+ XConfigureWindow(wm->display, client->frame, value_mask, &xwc);
- wm_client_focus(wm, ((TreeNode*)clients->nodes[0])->client);
+ if (wm->config.show_titlebar) {
+ xwc.y = wm->titlebar_font->height * 2;
+ xwc.x = 0;
+ xwc.height -= wm->titlebar_font->height * 2;
+ } else {
+ xwc.y = 0;
+ xwc.x = 0;
+ }
+
+ XConfigureWindow(wm->display, client->window, value_mask, &xwc);
+
+ wm_client_draw_frame(wm, client);
+ }
XEvent e;
XSync(wm->display, False);
@@ -444,6 +455,42 @@ void wm_init(Wm *wm)
// exit(1);
// }
+ // initialize titlebar font
+ int screen = DefaultScreen(wm->display);
+ wm->titlebar_font = XftFontOpenName(wm->display, screen, wm->config.titlebar_font);
+ if (!wm->titlebar_font) {
+ fprintf(stderr, "wm: could not open font \"%s\". exiting.\n",
+ wm->config.titlebar_font);
+ exit(1);
+ }
+
+ // initialize titlebar colors
+ Visual *visual = DefaultVisual(wm->display, screen);
+ Colormap cmap = DefaultColormap(wm->display, screen);
+ int ret = XftColorAllocName(wm->display, visual, cmap, wm->config.titlebar_color,
+ &wm->titlebar_color);
+ if (ret == 0) {
+ fprintf(stderr, "wm: could not allocate color \"%s\". exiting.\n",
+ wm->config.titlebar_color);
+ exit(1);
+ }
+
+ ret = XftColorAllocName(wm->display, visual, cmap, wm->config.titlebar_focused_color,
+ &wm->titlebar_focused_color);
+ if (ret == 0) {
+ fprintf(stderr, "wm: could not allocate color \"%s\". exiting.\n",
+ wm->config.titlebar_focused_color);
+ exit(1);
+ }
+
+ ret = XftColorAllocName(wm->display, visual, cmap, wm->config.titlebar_text_color,
+ &wm->titlebar_text_color);
+ if (ret == 0) {
+ fprintf(stderr, "wm: could not allocate color \"%s\". exiting.\n",
+ wm->config.titlebar_text_color);
+ exit(1);
+ }
+
wm_set_supported_atoms(wm);
wm->dock = ULONG_MAX;
@@ -479,6 +526,15 @@ void wm_exit(Wm *wm)
}
}
+ // free titlebar font and colors
+ int screen = DefaultScreen(wm->display);
+ Visual *visual = DefaultVisual(wm->display, screen);
+ Colormap cmap = DefaultColormap(wm->display, screen);
+ XftColorFree(wm->display, visual, cmap, &wm->titlebar_color);
+ XftColorFree(wm->display, visual, cmap, &wm->titlebar_focused_color);
+ XftColorFree(wm->display, visual, cmap, &wm->titlebar_text_color);
+ XftFontClose(wm->display, wm->titlebar_font);
+
XCloseDisplay(wm->display);
exit(EXIT_SUCCESS);
diff --git a/src/wm.h b/src/wm.h
index fd27f16..36fea10 100644
--- a/src/wm.h
+++ b/src/wm.h
@@ -29,6 +29,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include
#include
#include
@@ -126,6 +127,11 @@ struct Wm {
Config config;
+ XftColor titlebar_color;
+ XftColor titlebar_focused_color;
+ XftFont *titlebar_font;
+ XftColor titlebar_text_color;
+
bool running;
bool log_after_maprequest;
int socket_fd;