绘制 tag 标识
This commit is contained in:
@@ -60,8 +60,10 @@ const rule_t rules[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *const bar_bg = "#222222";
|
const char *const bar_bg = "#222222";
|
||||||
|
const char *const tag_bg = "#222222";
|
||||||
|
const char *const active_tag_bg = "#005577";
|
||||||
const char *const tag_color = "#bbbbbb";
|
const char *const tag_color = "#bbbbbb";
|
||||||
const char *const active_tag_color = "#005577";
|
const char *const active_tag_color = "#eeeeee";
|
||||||
const char *const layout_color = "#bbbbbb";
|
const char *const layout_color = "#bbbbbb";
|
||||||
const char *const client_name_color = "#bbbbbb";
|
const char *const client_name_color = "#bbbbbb";
|
||||||
const char *const active_client_name_color = "#005577";
|
const char *const active_client_name_color = "#005577";
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@@ -11,4 +12,6 @@ uint32_t *generate_wallpaper(const wallpaper_config_t *wallpaper_config,
|
|||||||
|
|
||||||
uint32_t get_font_height(const char *font_family, const uint32_t font_size,
|
uint32_t get_font_height(const char *font_family, const uint32_t font_size,
|
||||||
const uint32_t dpi);
|
const uint32_t dpi);
|
||||||
|
void draw_bar(monitor_t *monitor, bool is_current_monitor,
|
||||||
|
color_set_t *color_set, uint32_t height, uint32_t tag_x_padding);
|
||||||
void clean_pango_context(void);
|
void clean_pango_context(void);
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ typedef struct color_t {
|
|||||||
} color_t;
|
} color_t;
|
||||||
typedef struct color_set_t {
|
typedef struct color_set_t {
|
||||||
color_t bar_bg;
|
color_t bar_bg;
|
||||||
|
color_t tag_bg;
|
||||||
|
color_t active_tag_bg;
|
||||||
color_t tag_color;
|
color_t tag_color;
|
||||||
color_t active_tag_color;
|
color_t active_tag_color;
|
||||||
color_t layout_color;
|
color_t layout_color;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
bool has_other_wm_running(void);
|
bool has_other_wm_running(void);
|
||||||
int get_xcb_connection_fd(void);
|
int get_xcb_connection_fd(void);
|
||||||
|
void flush_xcb_connection(void);
|
||||||
|
|
||||||
typedef enum cursor_t {
|
typedef enum cursor_t {
|
||||||
cursor_normal = XC_left_ptr,
|
cursor_normal = XC_left_ptr,
|
||||||
|
|||||||
24
src/main.c
24
src/main.c
@@ -27,12 +27,14 @@ static void init_color_set(void);
|
|||||||
static void parse_color(const char *hex, color_t *color);
|
static void parse_color(const char *hex, color_t *color);
|
||||||
static void init_monitor_bar(void);
|
static void init_monitor_bar(void);
|
||||||
static void get_xresource_config(void);
|
static void get_xresource_config(void);
|
||||||
|
static void update_bars(void);
|
||||||
static void init_xcb_event_loop(void);
|
static void init_xcb_event_loop(void);
|
||||||
static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition,
|
static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition,
|
||||||
gpointer userdata);
|
gpointer userdata);
|
||||||
static void cleanup(void);
|
static void cleanup(void);
|
||||||
|
|
||||||
static monitor_t *monitors = NULL;
|
static monitor_t *monitors = NULL;
|
||||||
|
static monitor_t *current_monitor = NULL;
|
||||||
static wallpaper_config_t *wallpaper_config = NULL;
|
static wallpaper_config_t *wallpaper_config = NULL;
|
||||||
static color_set_t *color_set = NULL;
|
static color_set_t *color_set = NULL;
|
||||||
static GMainLoop *loop = NULL;
|
static GMainLoop *loop = NULL;
|
||||||
@@ -64,6 +66,8 @@ static void print_color(const char *prompt, const color_t *color) {
|
|||||||
}
|
}
|
||||||
static void print_color_set(color_set_t *set) {
|
static void print_color_set(color_set_t *set) {
|
||||||
print_color("== bar bg:", &set->bar_bg);
|
print_color("== bar bg:", &set->bar_bg);
|
||||||
|
print_color("== tag bg:", &set->tag_bg);
|
||||||
|
print_color("== active tag bg:", &set->active_tag_bg);
|
||||||
print_color("== tag color:", &set->tag_color);
|
print_color("== tag color:", &set->tag_color);
|
||||||
print_color("== active tag color:", &set->active_tag_color);
|
print_color("== active tag color:", &set->active_tag_color);
|
||||||
print_color("== layout bg:", &set->layout_color);
|
print_color("== layout bg:", &set->layout_color);
|
||||||
@@ -112,6 +116,7 @@ void init_monitors(void) {
|
|||||||
prev_monitor->next = m;
|
prev_monitor->next = m;
|
||||||
} else {
|
} else {
|
||||||
monitors = m;
|
monitors = m;
|
||||||
|
current_monitor = m;
|
||||||
}
|
}
|
||||||
prev_monitor = m;
|
prev_monitor = m;
|
||||||
|
|
||||||
@@ -122,6 +127,7 @@ void init_monitors(void) {
|
|||||||
}
|
}
|
||||||
for (monitor_t *m = monitors; m; m = m->next) {
|
for (monitor_t *m = monitors; m; m = m->next) {
|
||||||
m->tags = get_monitor_tags(i, m->index);
|
m->tags = get_monitor_tags(i, m->index);
|
||||||
|
m->selected_tag = 0x1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +242,8 @@ void free_wallpaper_config(wallpaper_config_t *wallpaper_config) {
|
|||||||
void init_color_set(void) {
|
void init_color_set(void) {
|
||||||
color_set = ecalloc(1, sizeof(color_set_t));
|
color_set = ecalloc(1, sizeof(color_set_t));
|
||||||
char *bar_background = NULL;
|
char *bar_background = NULL;
|
||||||
|
char *tag_background = NULL;
|
||||||
|
char *active_tag_background = NULL;
|
||||||
char *tag = NULL;
|
char *tag = NULL;
|
||||||
char *active_tag = NULL;
|
char *active_tag = NULL;
|
||||||
char *layout = NULL;
|
char *layout = NULL;
|
||||||
@@ -246,6 +254,9 @@ void init_color_set(void) {
|
|||||||
char *active_border = NULL;
|
char *active_border = NULL;
|
||||||
|
|
||||||
get_xresource_string("zswm.color.bar_bg", &bar_background, bar_bg);
|
get_xresource_string("zswm.color.bar_bg", &bar_background, bar_bg);
|
||||||
|
get_xresource_string("zswm.color.tag_bg", &tag_background, tag_bg);
|
||||||
|
get_xresource_string("zswm.color.active_tag_bg", &active_tag_background,
|
||||||
|
active_tag_bg);
|
||||||
get_xresource_string("zswm.color.tag", &tag, tag_color);
|
get_xresource_string("zswm.color.tag", &tag, tag_color);
|
||||||
get_xresource_string("zswm.color.active_tag", &active_tag, active_tag_color);
|
get_xresource_string("zswm.color.active_tag", &active_tag, active_tag_color);
|
||||||
get_xresource_string("zswm.color.layout", &layout, layout_color);
|
get_xresource_string("zswm.color.layout", &layout, layout_color);
|
||||||
@@ -259,6 +270,8 @@ void init_color_set(void) {
|
|||||||
active_border_color);
|
active_border_color);
|
||||||
|
|
||||||
parse_color(bar_background, &color_set->bar_bg);
|
parse_color(bar_background, &color_set->bar_bg);
|
||||||
|
parse_color(tag_background, &color_set->tag_bg);
|
||||||
|
parse_color(active_tag_background, &color_set->active_tag_bg);
|
||||||
parse_color(tag, &color_set->tag_color);
|
parse_color(tag, &color_set->tag_color);
|
||||||
parse_color(active_tag, &color_set->active_tag_color);
|
parse_color(active_tag, &color_set->active_tag_color);
|
||||||
parse_color(layout, &color_set->layout_color);
|
parse_color(layout, &color_set->layout_color);
|
||||||
@@ -269,6 +282,8 @@ void init_color_set(void) {
|
|||||||
parse_color(active_border, &color_set->active_border_color);
|
parse_color(active_border, &color_set->active_border_color);
|
||||||
|
|
||||||
free(bar_background);
|
free(bar_background);
|
||||||
|
free(tag_background);
|
||||||
|
free(active_tag_background);
|
||||||
free(tag);
|
free(tag);
|
||||||
free(active_tag);
|
free(active_tag);
|
||||||
free(layout);
|
free(layout);
|
||||||
@@ -330,6 +345,13 @@ void get_xresource_config(void) {
|
|||||||
clean_xresource();
|
clean_xresource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_bars(void) {
|
||||||
|
for (monitor_t *m = monitors; m; m = m->next) {
|
||||||
|
draw_bar(m, m == current_monitor, color_set, bar_height, tag_x_padding);
|
||||||
|
}
|
||||||
|
flush_xcb_connection();
|
||||||
|
}
|
||||||
|
|
||||||
void init_xcb_event_loop(void) {
|
void init_xcb_event_loop(void) {
|
||||||
GIOChannel *channel = g_io_channel_unix_new(get_xcb_connection_fd());
|
GIOChannel *channel = g_io_channel_unix_new(get_xcb_connection_fd());
|
||||||
g_io_channel_set_encoding(channel, NULL, NULL);
|
g_io_channel_set_encoding(channel, NULL, NULL);
|
||||||
@@ -392,6 +414,8 @@ int main(int argc, char *argv[]) {
|
|||||||
set_root_cursor(cursor_normal);
|
set_root_cursor(cursor_normal);
|
||||||
init_wallpaper();
|
init_wallpaper();
|
||||||
|
|
||||||
|
update_bars();
|
||||||
|
|
||||||
window_list_t *window_list = scan_window_list();
|
window_list_t *window_list = scan_window_list();
|
||||||
|
|
||||||
print_monitor_list_info(monitors);
|
print_monitor_list_info(monitors);
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
#include <cairo.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <glib.h>
|
||||||
#include <pango/pango-attributes.h>
|
#include <pango/pango-attributes.h>
|
||||||
#include <pango/pango-context.h>
|
#include <pango/pango-context.h>
|
||||||
#include <pango/pango-font.h>
|
#include <pango/pango-font.h>
|
||||||
@@ -6,12 +8,16 @@
|
|||||||
#include <pango/pango-layout.h>
|
#include <pango/pango-layout.h>
|
||||||
#include <pango/pango-types.h>
|
#include <pango/pango-types.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
static PangoContext *context = NULL;
|
static PangoContext *context = NULL;
|
||||||
|
static PangoAttrList *attr_list = NULL;
|
||||||
|
static PangoLayout *layout = NULL;
|
||||||
|
|
||||||
uint32_t get_font_height(const char *font_family, const uint32_t font_size,
|
uint32_t get_font_height(const char *font_family, const uint32_t font_size,
|
||||||
const uint32_t dpi) {
|
const uint32_t dpi) {
|
||||||
@@ -22,14 +28,13 @@ uint32_t get_font_height(const char *font_family, const uint32_t font_size,
|
|||||||
|
|
||||||
pango_cairo_context_set_resolution(context, dpi);
|
pango_cairo_context_set_resolution(context, dpi);
|
||||||
PangoLanguage *lang = pango_context_get_language(context);
|
PangoLanguage *lang = pango_context_get_language(context);
|
||||||
PangoAttrList *attr_list = pango_attr_list_new();
|
attr_list = pango_attr_list_new();
|
||||||
|
|
||||||
PangoFontDescription *desc = pango_font_description_from_string(font_family);
|
PangoFontDescription *desc = pango_font_description_from_string(font_family);
|
||||||
pango_font_description_set_size(desc, font_size * PANGO_SCALE);
|
pango_font_description_set_size(desc, font_size * PANGO_SCALE);
|
||||||
|
|
||||||
PangoAttribute *attr = pango_attr_font_desc_new(desc);
|
PangoAttribute *attr = pango_attr_font_desc_new(desc);
|
||||||
pango_attr_list_insert(attr_list, attr);
|
pango_attr_list_insert(attr_list, attr);
|
||||||
pango_attr_list_unref(attr_list);
|
|
||||||
|
|
||||||
PangoFontMetrics *metrics = pango_context_get_metrics(context, desc, lang);
|
PangoFontMetrics *metrics = pango_context_get_metrics(context, desc, lang);
|
||||||
int ascent = pango_font_metrics_get_ascent(metrics);
|
int ascent = pango_font_metrics_get_ascent(metrics);
|
||||||
@@ -43,9 +48,108 @@ uint32_t get_font_height(const char *font_family, const uint32_t font_size,
|
|||||||
return font_height;
|
return font_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw_background(cairo_t *cr, color_t *color, int32_t x, int32_t y,
|
||||||
|
uint32_t width, uint32_t height) {
|
||||||
|
cairo_move_to(cr, x, y);
|
||||||
|
cairo_set_source_rgba(cr, color->red, color->green, color->blue,
|
||||||
|
color->alpha);
|
||||||
|
cairo_rectangle(cr, x, y, width, height);
|
||||||
|
cairo_fill(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prepare_layout(bool align_center) {
|
||||||
|
if (!layout) {
|
||||||
|
layout = pango_layout_new(context);
|
||||||
|
pango_layout_set_attributes(layout, attr_list);
|
||||||
|
pango_layout_set_wrap(layout, PANGO_WRAP_NONE);
|
||||||
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
PangoAlignment align = align_center ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT;
|
||||||
|
pango_layout_set_alignment(layout, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_layout_size(PangoLayout *layout, int *width, int *height) {
|
||||||
|
PangoRectangle ink_rect, logical_rect;
|
||||||
|
pango_layout_get_pixel_extents(layout, &ink_rect, &logical_rect);
|
||||||
|
|
||||||
|
int w = MAX(ink_rect.width, logical_rect.width);
|
||||||
|
int h = MAX(ink_rect.height, logical_rect.height);
|
||||||
|
if (width) *width = w;
|
||||||
|
if (height) *height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t get_text_width(const char *text) {
|
||||||
|
prepare_layout(false);
|
||||||
|
pango_layout_set_width(layout, -1);
|
||||||
|
pango_layout_set_text(layout, text, -1);
|
||||||
|
int w;
|
||||||
|
get_layout_size(layout, &w, NULL);
|
||||||
|
return (uint32_t)w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_text(cairo_t *cr, const char *text, color_t *color, int32_t x,
|
||||||
|
uint32_t y, uint32_t width, uint32_t height,
|
||||||
|
bool align_center) {
|
||||||
|
prepare_layout(align_center);
|
||||||
|
pango_layout_set_width(layout, width * PANGO_SCALE);
|
||||||
|
pango_layout_set_text(layout, text, -1);
|
||||||
|
cairo_set_source_rgba(cr, color->red, color->green, color->blue,
|
||||||
|
color->alpha);
|
||||||
|
int h = 0;
|
||||||
|
get_layout_size(layout, NULL, &h);
|
||||||
|
double ty = ((double)height - h) / 2;
|
||||||
|
|
||||||
|
pango_cairo_update_layout(cr, layout);
|
||||||
|
cairo_move_to(cr, x, y + ty);
|
||||||
|
pango_cairo_show_layout(cr, layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clean_cairo_context(cairo_t *cr) {
|
||||||
|
cairo_save(cr);
|
||||||
|
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
||||||
|
cairo_paint(cr);
|
||||||
|
cairo_restore(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_bar(monitor_t *monitor, bool is_current_monitor,
|
||||||
|
color_set_t *color_set, uint32_t height, uint32_t tag_x_padding) {
|
||||||
|
cairo_t *cr = monitor->cr;
|
||||||
|
int32_t x = 0;
|
||||||
|
uint32_t width = 0;
|
||||||
|
const char *text;
|
||||||
|
color_t *color;
|
||||||
|
|
||||||
|
clean_cairo_context(cr);
|
||||||
|
draw_background(cr, &color_set->bar_bg, 0, 0, monitor->monitor_width, height);
|
||||||
|
|
||||||
|
/* 绘制 tags */
|
||||||
|
for (int i = 0; i < g_strv_length(monitor->tags); i++) {
|
||||||
|
bool selected = (monitor->selected_tag >> i) & 0x1;
|
||||||
|
text = monitor->tags[i];
|
||||||
|
width = get_text_width(text) + tag_x_padding * 2;
|
||||||
|
|
||||||
|
color = selected ? &color_set->active_tag_bg : &color_set->tag_bg;
|
||||||
|
if (color->rgba != color_set->bar_bg.rgba) {
|
||||||
|
draw_background(cr, color, x, 0, width, height);
|
||||||
|
}
|
||||||
|
color = selected ? &color_set->active_tag_color : &color_set->tag_color;
|
||||||
|
draw_text(cr, text, color, x, 0, width, height, true);
|
||||||
|
x += width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void clean_pango_context(void) {
|
void clean_pango_context(void) {
|
||||||
if (!context) return;
|
if (layout) {
|
||||||
|
g_object_unref(layout);
|
||||||
g_object_unref(context);
|
layout = NULL;
|
||||||
context = NULL;
|
}
|
||||||
|
if (attr_list) {
|
||||||
|
pango_attr_list_unref(attr_list);
|
||||||
|
attr_list = NULL;
|
||||||
|
}
|
||||||
|
if (context) {
|
||||||
|
g_object_unref(context);
|
||||||
|
context = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ bool has_other_wm_running(void) {
|
|||||||
*/
|
*/
|
||||||
int get_xcb_connection_fd(void) { return xcb_get_file_descriptor(conn); }
|
int get_xcb_connection_fd(void) { return xcb_get_file_descriptor(conn); }
|
||||||
|
|
||||||
|
void flush_xcb_connection(void) { xcb_flush(conn); }
|
||||||
|
|
||||||
/* xinerama 扩展是否激活 */
|
/* xinerama 扩展是否激活 */
|
||||||
static bool xinerama_active(void) {
|
static bool xinerama_active(void) {
|
||||||
const char *name = "XINERAMA";
|
const char *name = "XINERAMA";
|
||||||
|
|||||||
Reference in New Issue
Block a user