Compare commits

...

3 Commits

9 changed files with 169 additions and 9 deletions

View File

@ -3,7 +3,8 @@ EXT=.c
FLAGS=-O0 -g
DEBUG_FLAGS=-DDEBUG -fsanitize=undefined -fsanitize=address
DEPFLAGS=-MD -MP
LIBS=$(shell pkg-config --libs xcb x11 xinerama json-c)
LIBS=$(shell pkg-config --libs xcb x11 xinerama xft json-c cmocka)
FLAGS+=$(shell pkg-config --cflags xcb x11 xinerama xft json-c cmocka)
EXEC_NAME=wm
OBJDIR=obj

View File

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h"
#include "util.h"
#include "wm.h"
#include <X11/Xft/Xft.h>
#include <X11/Xlib.h>
#include <assert.h>
#include <stdio.h>
@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -631,7 +631,11 @@ static void test_wm_config(void **state)
"focused_border_color #445566\n"
"border_width 1\n"
"keybind Windows+Alt+Shift+h focus left\n"
"focus_on_motion true\n";
"show_titlebar true\n"
"titlebar_color #001234\n"
"titlebar_focused_color #004321\n"
"titlebar_font monospace:size=17:antialias=true\n"
"titlebar_text_color #aabbcc\n";
char tmp[] = "/tmp/XXXXXX";
mkstemp(tmp);
@ -675,6 +679,11 @@ static void test_wm_config(void **state)
assert_true(found_keybind);
assert_true(config.focus_on_motion);
assert_true(config.show_titlebar);
assert_string_equal(config.titlebar_color, "#001234");
assert_string_equal(config.titlebar_focused_color, "#004321");
assert_string_equal(config.titlebar_font, "monospace:size=17:antialias=true");
assert_string_equal(config.titlebar_text_color, "#aabbcc");
wm_configfile_free(&file);
wm_keybinds_free(&config);

View File

@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xinerama.h>
#include <X11/Xft/Xft.h>
#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);

View File

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xinerama.h>
#include <X11/Xft/Xft.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
@ -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;