绘制任务栏
This commit is contained in:
68
src/client.c
68
src/client.c
@@ -8,6 +8,7 @@
|
|||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "atoms-extern.h"
|
#include "atoms-extern.h"
|
||||||
|
#include "monitor.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
@@ -56,17 +57,58 @@ task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void client_add_to_tag(client_t *client, tag_t *tag) {
|
||||||
|
if (client_get_task_in_tag(client, tag)) return;
|
||||||
|
|
||||||
|
task_in_tag_t *task = p_new(task_in_tag_t, 1);
|
||||||
|
task->client = client;
|
||||||
|
task->next = tag->task_list;
|
||||||
|
tag->task_list = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_remove_from_tag(client_t *client, tag_t *tag) {
|
||||||
|
for (task_in_tag_t **task = &tag->task_list; *task; task = &(*task)->next) {
|
||||||
|
if ((*task)->client != client) continue;
|
||||||
|
p_delete(task);
|
||||||
|
*task = (*task)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void client_wipe(client_t *client) {
|
||||||
|
p_delete(&client->class);
|
||||||
|
p_delete(&client->instance);
|
||||||
|
p_delete(&client->name);
|
||||||
|
p_delete(&client->icon_name);
|
||||||
|
p_delete(&client->net_name);
|
||||||
|
p_delete(&client->net_icon_name);
|
||||||
|
p_delete(&client->role);
|
||||||
|
p_delete(&client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void client_tags_apply(client_t *client) {
|
||||||
|
for (tag_t *tag = client->monitor->tag_list; tag; tag = tag->next) {
|
||||||
|
if (client->tags & tag->mask) {
|
||||||
|
client_add_to_tag(client, tag);
|
||||||
|
} else {
|
||||||
|
client_remove_from_tag(client, tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->tags == 0) client_wipe(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void client_update_names(client_t *c) {
|
||||||
|
xwindow_get_text_property(c->window, WM_NAME, &c->name);
|
||||||
|
xwindow_get_text_property(c->window, WM_ICON_NAME, &c->icon_name);
|
||||||
|
xwindow_get_text_property(c->window, _NET_WM_NAME, &c->net_name);
|
||||||
|
xwindow_get_text_property(c->window, _NET_WM_ICON_NAME, &c->net_icon_name);
|
||||||
|
}
|
||||||
|
|
||||||
void client_manage(xcb_window_t window,
|
void client_manage(xcb_window_t window,
|
||||||
xcb_get_geometry_reply_t *geometry_reply) {
|
xcb_get_geometry_reply_t *geometry_reply) {
|
||||||
client_t *c = p_new(client_t, 1);
|
client_t *c = p_new(client_t, 1);
|
||||||
c->window = window;
|
c->window = window;
|
||||||
|
|
||||||
c->name = xwindow_get_text_property(c->window, WM_NAME);
|
|
||||||
c->icon_name = xwindow_get_text_property(c->window, WM_ICON_NAME);
|
|
||||||
c->net_name = xwindow_get_text_property(c->window, _NET_WM_NAME);
|
|
||||||
c->net_icon_name = xwindow_get_text_property(c->window, _NET_WM_ICON_NAME);
|
|
||||||
c->role = xwindow_get_text_property(c->window, WM_WINDOW_ROLE);
|
|
||||||
|
|
||||||
client_attach_list(c);
|
client_attach_list(c);
|
||||||
client_attach_stack(c);
|
client_attach_stack(c);
|
||||||
|
|
||||||
@@ -79,6 +121,7 @@ void client_manage(xcb_window_t window,
|
|||||||
c->instance = strdup(prop.instance_name);
|
c->instance = strdup(prop.instance_name);
|
||||||
xcb_icccm_get_wm_class_reply_wipe(&prop);
|
xcb_icccm_get_wm_class_reply_wipe(&prop);
|
||||||
}
|
}
|
||||||
|
xwindow_get_text_property(c->window, WM_WINDOW_ROLE, &c->role);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -96,8 +139,11 @@ void client_manage(xcb_window_t window,
|
|||||||
c->monitor = wm.current_monitor;
|
c->monitor = wm.current_monitor;
|
||||||
c->tags = c->monitor->selected_tag->mask;
|
c->tags = c->monitor->selected_tag->mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client_tags_apply(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
monitor_arrange(c->monitor);
|
||||||
{
|
{
|
||||||
const xcb_params_cw_t params = {
|
const xcb_params_cw_t params = {
|
||||||
.event_mask = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE |
|
.event_mask = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE |
|
||||||
@@ -109,9 +155,19 @@ void client_manage(xcb_window_t window,
|
|||||||
xcb_map_window(wm.xcb_conn, window);
|
xcb_map_window(wm.xcb_conn, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client_update_names(c);
|
||||||
|
monitor_draw_bar(c->monitor);
|
||||||
xcb_flush(wm.xcb_conn);
|
xcb_flush(wm.xcb_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **client_get_task_title(client_t *client) {
|
||||||
|
if (client->net_icon_name) return &client->net_icon_name;
|
||||||
|
if (client->net_name) return &client->net_name;
|
||||||
|
if (client->icon_name) return &client->icon_name;
|
||||||
|
if (client->name) return &client->name;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool client_need_layout(client_t *client) {
|
bool client_need_layout(client_t *client) {
|
||||||
if (client->floating || client->fullscreen || client->maximize ||
|
if (client->floating || client->fullscreen || client->maximize ||
|
||||||
client->minimize) {
|
client->minimize) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ client_t *client_get_by_window(xcb_window_t window);
|
|||||||
task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag);
|
task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag);
|
||||||
void client_manage(xcb_window_t window,
|
void client_manage(xcb_window_t window,
|
||||||
xcb_get_geometry_reply_t *geometry_reply);
|
xcb_get_geometry_reply_t *geometry_reply);
|
||||||
|
char **client_get_task_title(client_t *client);
|
||||||
bool client_need_layout(client_t *client);
|
bool client_need_layout(client_t *client);
|
||||||
|
|
||||||
void client_send_to_tag(client_t *client, uint32_t tag_mask);
|
void client_send_to_tag(client_t *client, uint32_t tag_mask);
|
||||||
|
|||||||
26
src/event.c
26
src/event.c
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <string.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_event.h>
|
#include <xcb/xcb_event.h>
|
||||||
#include <xcb/xcb_keysyms.h>
|
#include <xcb/xcb_keysyms.h>
|
||||||
@@ -10,12 +10,15 @@
|
|||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
|
#include "atoms-extern.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "default_config.h"
|
#include "default_config.h"
|
||||||
|
#include "monitor.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
#include "xkb.h"
|
#include "xkb.h"
|
||||||
|
#include "xwindow.h"
|
||||||
|
|
||||||
static void button_press(xcb_button_press_event_t *ev) {
|
static void button_press(xcb_button_press_event_t *ev) {
|
||||||
click_area_t click_area = click_none;
|
click_area_t click_area = click_none;
|
||||||
@@ -116,6 +119,26 @@ static void map_request(xcb_map_request_event_t *ev) {
|
|||||||
p_delete(&wa_reply);
|
p_delete(&wa_reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void property_notify(xcb_property_notify_event_t *ev) {
|
||||||
|
client_t *client = client_get_by_window(ev->window);
|
||||||
|
if (client == nullptr) return;
|
||||||
|
|
||||||
|
if (ev->atom == WM_NAME) {
|
||||||
|
xwindow_get_text_property(ev->window, ev->atom, &client->name);
|
||||||
|
monitor_draw_bar(client->monitor);
|
||||||
|
} else if (ev->atom == WM_ICON_NAME) {
|
||||||
|
if (client->icon_name) p_delete(&client->icon_name);
|
||||||
|
xwindow_get_text_property(ev->window, ev->atom, &client->icon_name);
|
||||||
|
monitor_draw_bar(client->monitor);
|
||||||
|
} else if (ev->atom == _NET_WM_NAME) {
|
||||||
|
xwindow_get_text_property(ev->window, ev->atom, &client->net_name);
|
||||||
|
monitor_draw_bar(client->monitor);
|
||||||
|
} else if (ev->atom == _NET_WM_ICON_NAME) {
|
||||||
|
xwindow_get_text_property(ev->window, ev->atom, &client->net_icon_name);
|
||||||
|
monitor_draw_bar(client->monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_xcb_event(xcb_generic_event_t *event) {
|
static void handle_xcb_event(xcb_generic_event_t *event) {
|
||||||
uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(event);
|
uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(event);
|
||||||
const char *label = xcb_event_get_label(event_type);
|
const char *label = xcb_event_get_label(event_type);
|
||||||
@@ -133,6 +156,7 @@ static void handle_xcb_event(xcb_generic_event_t *event) {
|
|||||||
EVENT(XCB_KEY_RELEASE, key_press);
|
EVENT(XCB_KEY_RELEASE, key_press);
|
||||||
EVENT(XCB_CONFIGURE_REQUEST, configure_request);
|
EVENT(XCB_CONFIGURE_REQUEST, configure_request);
|
||||||
EVENT(XCB_MAP_REQUEST, map_request);
|
EVENT(XCB_MAP_REQUEST, map_request);
|
||||||
|
EVENT(XCB_PROPERTY_NOTIFY, property_notify);
|
||||||
|
|
||||||
#undef EVENT
|
#undef EVENT
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,6 +197,34 @@ static void monitor_draw_layout_symbol(monitor_t *monitor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void monitor_draw_tasks(monitor_t *monitor) {
|
||||||
|
task_in_tag_t *task_list = monitor->selected_tag->task_list;
|
||||||
|
if (!task_list) return;
|
||||||
|
|
||||||
|
uint16_t task_count = 0;
|
||||||
|
for (task_in_tag_t *task = task_list; task; task = task->next) ++task_count;
|
||||||
|
if (task_count == 0) return;
|
||||||
|
|
||||||
|
int16_t x = monitor->layout_symbol_extent.end;
|
||||||
|
uint16_t task_width = (monitor->geometry.width - x) / task_count;
|
||||||
|
for (task_in_tag_t *task = task_list; task; task = task->next) {
|
||||||
|
task->bar_extent.start = x;
|
||||||
|
task->bar_extent.end = x + task_width;
|
||||||
|
x += task_width;
|
||||||
|
|
||||||
|
char **title = client_get_task_title(task->client);
|
||||||
|
if (title == nullptr || *title == nullptr) continue;
|
||||||
|
color_t *color = &wm.color_set.active_tag_color;
|
||||||
|
area_t area = {
|
||||||
|
.x = task->bar_extent.start,
|
||||||
|
.y = monitor->geometry.y,
|
||||||
|
.width = task_width,
|
||||||
|
.height = wm.bar_height,
|
||||||
|
};
|
||||||
|
draw_text(monitor->bar_cr, *title, color, area, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void monitor_draw_bar(monitor_t *monitor) {
|
void monitor_draw_bar(monitor_t *monitor) {
|
||||||
cairo_t *cr = monitor->bar_cr;
|
cairo_t *cr = monitor->bar_cr;
|
||||||
uint16_t height = wm.bar_height;
|
uint16_t height = wm.bar_height;
|
||||||
@@ -210,6 +238,7 @@ void monitor_draw_bar(monitor_t *monitor) {
|
|||||||
|
|
||||||
monitor_draw_tags(monitor);
|
monitor_draw_tags(monitor);
|
||||||
monitor_draw_layout_symbol(monitor);
|
monitor_draw_layout_symbol(monitor);
|
||||||
|
monitor_draw_tasks(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void monitor_arrange(monitor_t *monitor) {
|
void monitor_arrange(monitor_t *monitor) {
|
||||||
|
|||||||
Reference in New Issue
Block a user