Compare commits

...

3 Commits

9 changed files with 169 additions and 9 deletions

View File

@ -3,7 +3,8 @@ EXT=.c
FLAGS=-O0 -g FLAGS=-O0 -g
DEBUG_FLAGS=-DDEBUG -fsanitize=undefined -fsanitize=address DEBUG_FLAGS=-DDEBUG -fsanitize=undefined -fsanitize=address
DEPFLAGS=-MD -MP 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 EXEC_NAME=wm
OBJDIR=obj OBJDIR=obj

View File

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h" #include "client.h"
#include "util.h" #include "util.h"
#include "wm.h" #include "wm.h"
#include <X11/Xft/Xft.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@ -162,6 +163,7 @@ void wm_client_hide(Wm *wm, Client *c)
return; return;
c->hidden = true; c->hidden = true;
XUnmapWindow(wm->display, c->frame);
XUnmapWindow(wm->display, c->window); XUnmapWindow(wm->display, c->window);
} }
@ -173,6 +175,7 @@ void wm_client_show(Wm *wm, Client *c)
return; return;
c->hidden = false; c->hidden = false;
XMapWindow(wm->display, c->frame);
XMapWindow(wm->display, c->window); 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); TreeNode *node = wm_treenode_ptr_find_client_node(c->ws->tree, c);
c->ws->focused_node = node; c->ws->focused_node = node;
wm_monitor_clients_border(wm, c->m); 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) 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) if (XSendEvent(wm->display, c->window, false, NoEventMask, &event) != Success)
XKillClient(wm->display, c->window); XKillClient(wm->display, c->window);
XDestroyWindow(wm->display, c->frame);
TreeNode* parent = wm_treenode_remove_client(wm, c->ws->tree, c); TreeNode* parent = wm_treenode_remove_client(wm, c->ws->tree, c);
wm_client_free(wm, c); wm_client_free(wm, c);
@ -470,3 +476,38 @@ bool wm_client_is_focused(Wm *wm, Client *c)
return false; 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; bool hidden;
Monitor *m; Monitor *m;
Window window; Window window;
Window frame;
Client *prev; Client *prev;
Client *next; Client *next;
char *name; char *name;
@ -72,6 +73,7 @@ void wm_client_border_focused(Wm* wm, Client *c);
void wm_monitor_clients_border(Wm* wm, Monitor *m); void wm_monitor_clients_border(Wm* wm, Monitor *m);
bool wm_client_is_focused(Wm* wm, Client *c); 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 #endif

View File

@ -57,10 +57,15 @@ static const KeybindFunctionCommand __wm_keybind_commands[] = {
void wm_cfg_init_def(Config *config) void wm_cfg_init_def(Config *config)
{ {
config->ms_p = 0.5; config->ms_p = 0.5;
strncpy(config->border_col, "#222222", CONFIG_COLOR_MAX); strcpy(config->border_col, "#222222");
strncpy(config->focused_border_col, "#444444", CONFIG_COLOR_MAX); strcpy(config->focused_border_col, "#444444");
config->border_width = 2; config->border_width = 2;
config->focus_on_motion = true; 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); 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, (ConfigCommand) {.string = "focus_on_motion", .arg_count = 1,
.cfg_var_offset[0] = offsetof(Config, focus_on_motion), .cfg_var_offset[0] = offsetof(Config, focus_on_motion),
.argc = 0, .arg_type = TYPE_BOOL}, .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]); 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) KeybindFunction wm_str_to_keybindfunction(const char* str)
{ {
DEBUG_PRINT("%s %s\n", __func__, str); DEBUG_PRINT("%s %s\n", __func__, str);
char lower[CONFIG_ARGLEN_MAX]; char lower[CONFIG_ARGLEN_MAX];
strncpy(lower, str, CONFIG_ARGLEN_MAX); strncpy(lower, str, CONFIG_ARGLEN_MAX);

View File

@ -87,6 +87,11 @@ typedef struct {
Keybind *keybinds; Keybind *keybinds;
int kb_count; int kb_count;
bool focus_on_motion; 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]; char log_path[PATH_MAX];
} Config; } 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__) 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); c = wm_client_create(wm, e.window);
RETURN_IF_NULL(c); RETURN_IF_NULL(c);
c->frame = frame;
wm_ws_tree_insert_client(wm, c->ws, c); 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" "focused_border_color #445566\n"
"border_width 1\n" "border_width 1\n"
"keybind Windows+Alt+Shift+h focus left\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"; char tmp[] = "/tmp/XXXXXX";
mkstemp(tmp); mkstemp(tmp);
@ -675,6 +679,11 @@ static void test_wm_config(void **state)
assert_true(found_keybind); assert_true(found_keybind);
assert_true(config.focus_on_motion); 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_configfile_free(&file);
wm_keybinds_free(&config); 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/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#include <X11/Xft/Xft.h>
#include "wm.h" #include "wm.h"
#include "config.h" #include "config.h"
#include "handler.h" #include "handler.h"
@ -317,11 +318,21 @@ void wm_layout(Wm *wm, Monitor *m)
unsigned int value_mask = CWX | CWY | CWWidth | CWHeight; unsigned int value_mask = CWX | CWY | CWWidth | CWHeight;
XWindowChanges xwc = wm_client_to_xwchanges((client)); XWindowChanges xwc = wm_client_to_xwchanges((client));
XConfigureWindow(wm->display, client->window, value_mask, &xwc); XConfigureWindow(wm->display, client->frame, value_mask, &xwc);
wm_client_show(wm, client);
}
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; XEvent e;
XSync(wm->display, False); XSync(wm->display, False);
@ -444,6 +455,42 @@ void wm_init(Wm *wm)
// exit(1); // 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_set_supported_atoms(wm);
wm->dock = ULONG_MAX; 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); XCloseDisplay(wm->display);
exit(EXIT_SUCCESS); 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/Xproto.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#include <X11/Xft/Xft.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
@ -126,6 +127,11 @@ struct Wm {
Config config; Config config;
XftColor titlebar_color;
XftColor titlebar_focused_color;
XftFont *titlebar_font;
XftColor titlebar_text_color;
bool running; bool running;
bool log_after_maprequest; bool log_after_maprequest;
int socket_fd; int socket_fd;