Compare commits
2 Commits
d82081ca71
...
4db9c4c078
| Author | SHA1 | Date | |
|---|---|---|---|
|
4db9c4c078
|
|||
|
16204bd638
|
3
Makefile
3
Makefile
@@ -24,6 +24,9 @@ run:
|
|||||||
wm: $(TARGET_NAME)
|
wm: $(TARGET_NAME)
|
||||||
DISPLAY=:3 $(TARGET)
|
DISPLAY=:3 $(TARGET)
|
||||||
|
|
||||||
|
debug: $(TARGET_NAME)
|
||||||
|
DISPLAY=:3 valgrind $(TARGET)
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
@cmake -S $(SRC_DIR) -B $(BUILD_DIR)
|
@cmake -S $(SRC_DIR) -B $(BUILD_DIR)
|
||||||
@cp $(BUILD_DIR)/compile_commands.json $(MAKEFILE_DIR)
|
@cp $(BUILD_DIR)/compile_commands.json $(MAKEFILE_DIR)
|
||||||
|
|||||||
@@ -15,15 +15,14 @@ project(${APP_NAME}
|
|||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(${APP_NAME} main.c utils.c)
|
add_executable(${APP_NAME} main.c utils.c config.c)
|
||||||
|
|
||||||
# use C17
|
# use C17
|
||||||
set_property(TARGET ${APP_NAME} PROPERTY C_STANDARD 17)
|
set_property(TARGET ${APP_NAME} PROPERTY C_STANDARD 17)
|
||||||
|
|
||||||
target_include_directories(${APP_NAME} PRIVATE "${SOURCE_DIR}/include")
|
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||||
pkg_check_modules(XCB REQUIRED
|
pkg_check_modules(XCB REQUIRED
|
||||||
xcb
|
xcb
|
||||||
xcb-cursor
|
xcb-cursor
|
||||||
@@ -35,14 +34,24 @@ pkg_check_modules(XCB REQUIRED
|
|||||||
xcb-xinerama
|
xcb-xinerama
|
||||||
xcb-xrm
|
xcb-xrm
|
||||||
)
|
)
|
||||||
target_include_directories(${APP_NAME} SYSTEM PUBLIC ${XCB_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
add_subdirectory(xcb)
|
add_subdirectory(xcb)
|
||||||
target_link_libraries(${APP_NAME} ${LIB_XCB_NAME})
|
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/app.h.in"
|
"${CMAKE_CURRENT_SOURCE_DIR}/app.h.in"
|
||||||
"${CMAKE_BINARY_DIR}/app.h"
|
"${CMAKE_BINARY_DIR}/app.h"
|
||||||
@ONLY
|
@ONLY
|
||||||
)
|
)
|
||||||
target_include_directories(${APP_NAME} PRIVATE ${CMAKE_BINARY_DIR})
|
|
||||||
|
target_include_directories(${APP_NAME} SYSTEM
|
||||||
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
target_include_directories(${APP_NAME}
|
||||||
|
PRIVATE "${SOURCE_DIR}/include"
|
||||||
|
PRIVATE ${CMAKE_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${APP_NAME}
|
||||||
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
|
PRIVATE ${LIB_XCB_NAME}
|
||||||
|
)
|
||||||
|
|||||||
6
src/config.c
Normal file
6
src/config.c
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* 壁纸列表,支持通配符和 shell 环境变量拼接,最后以 NULL 结尾 */
|
||||||
|
const char *wallpager_list[] = {NULL};
|
||||||
3
src/include/config.h
Normal file
3
src/include/config.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern const char *wallpager_list[];
|
||||||
61
src/include/types.h
Normal file
61
src/include/types.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct monitor_t monitor_t;
|
||||||
|
typedef struct client_t client_t;
|
||||||
|
|
||||||
|
typedef struct layout_t {
|
||||||
|
const char *symbol;
|
||||||
|
void (*arrange)(monitor_t *monitor);
|
||||||
|
} layout_t;
|
||||||
|
|
||||||
|
#define TAG_SYMBOL_LENGTH 32
|
||||||
|
|
||||||
|
/* 避免引入 xcb 头文件 */
|
||||||
|
typedef uint32_t xcb_window_t;
|
||||||
|
|
||||||
|
struct monitor_t {
|
||||||
|
uint32_t index;
|
||||||
|
int32_t monitor_x, monitor_y, window_x, window_y;
|
||||||
|
uint32_t monitor_width, monitor_height, window_width, window_height;
|
||||||
|
|
||||||
|
uint32_t selected_tag;
|
||||||
|
uint32_t tag_count;
|
||||||
|
char (*tags)[TAG_SYMBOL_LENGTH];
|
||||||
|
|
||||||
|
/* 为了避免引入 cairo 相关头文件,这里用 void *
|
||||||
|
* 指针代替实际的指针类型,使用时强转为相应指针类型使用即可 */
|
||||||
|
void *surface; /* cairo_surface_t */
|
||||||
|
void *cr; /* cairo_t */
|
||||||
|
|
||||||
|
const layout_t *layout;
|
||||||
|
monitor_t *next;
|
||||||
|
|
||||||
|
client_t *clients;
|
||||||
|
client_t *clients_stack;
|
||||||
|
client_t *selected_client;
|
||||||
|
|
||||||
|
xcb_window_t bar_window;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct client_t {
|
||||||
|
char name[256];
|
||||||
|
int32_t x, y;
|
||||||
|
uint32_t width, height, border_width;
|
||||||
|
uint32_t tags;
|
||||||
|
bool fullscreen;
|
||||||
|
bool floating;
|
||||||
|
|
||||||
|
monitor_t *monitor;
|
||||||
|
client_t *next;
|
||||||
|
client_t *stack_next;
|
||||||
|
|
||||||
|
xcb_window_t window;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct wallpaper_config_t {
|
||||||
|
uint32_t count;
|
||||||
|
char **path_list;
|
||||||
|
} wallpaper_config_t;
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define LENGTH(X) (sizeof(X) / sizeof(X)[0])
|
#define LENGTH(X) (sizeof(X) / sizeof(X)[0])
|
||||||
|
|
||||||
void die(const char *format, ...);
|
void die(const char *format, ...);
|
||||||
void *ecalloc(size_t number_of_member, size_t member_size);
|
void *ecalloc(size_t number_of_member, size_t member_size);
|
||||||
|
|
||||||
|
bool file_exist(const char *path);
|
||||||
|
|||||||
112
src/main.c
112
src/main.c
@@ -1,26 +1,120 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wordexp.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "xcb.h"
|
#include "xcb.h"
|
||||||
|
|
||||||
|
static void init_monitors(void);
|
||||||
|
static wallpaper_config_t *parse_wallpaper_config(const char **wallpapers);
|
||||||
|
static void free_wallpaper_config(wallpaper_config_t *wallpaper_config);
|
||||||
|
static void cleanup(void);
|
||||||
|
|
||||||
|
static monitor_t *monitors = NULL;
|
||||||
|
static wallpaper_config_t *wallpaper_config = NULL;
|
||||||
|
|
||||||
|
void init_monitors(void) {
|
||||||
|
monitor_rect_t *mr = detect_monitor_rect();
|
||||||
|
uint32_t i = 0;
|
||||||
|
while (mr) {
|
||||||
|
monitor_t *m = ecalloc(1, sizeof(monitor_t));
|
||||||
|
m->monitor_x = mr->x;
|
||||||
|
m->monitor_y = mr->y;
|
||||||
|
m->monitor_width = mr->width;
|
||||||
|
m->monitor_height = mr->height;
|
||||||
|
m->index = i;
|
||||||
|
|
||||||
|
printf("mon[%u]: x: %d, y: %d, w: %u, h: %u\n", i, mr->x, mr->y, mr->width,
|
||||||
|
mr->height);
|
||||||
|
|
||||||
|
if (!i) monitors = m;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
monitor_rect_t *next_mr = mr->next;
|
||||||
|
free(mr);
|
||||||
|
mr = next_mr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wallpaper_config_t *parse_wallpaper_config(const char **wallpapers) {
|
||||||
|
if (!wallpapers) return NULL;
|
||||||
|
|
||||||
|
wallpaper_config_t *wc = ecalloc(1, sizeof(wallpaper_config_t));
|
||||||
|
|
||||||
|
GStrvBuilder *builder = g_strv_builder_new();
|
||||||
|
for (int i = 0; wallpapers && wallpapers[i]; i++) {
|
||||||
|
wordexp_t p;
|
||||||
|
if (wordexp(wallpapers[i], &p, 0)) continue;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < p.we_wordc; i++) {
|
||||||
|
size_t len = strlen(p.we_wordv[i]) + 1;
|
||||||
|
char *realpath = ecalloc(len, sizeof(char));
|
||||||
|
strncpy(realpath, p.we_wordv[i], len);
|
||||||
|
g_strstrip(realpath);
|
||||||
|
if (file_exist(realpath)) g_strv_builder_add(builder, realpath);
|
||||||
|
|
||||||
|
free(realpath);
|
||||||
|
}
|
||||||
|
wordfree(&p);
|
||||||
|
}
|
||||||
|
|
||||||
|
wc->path_list = g_strv_builder_unref_to_strv(builder);
|
||||||
|
wc->count = g_strv_length(wc->path_list);
|
||||||
|
if (wc->count) return wc;
|
||||||
|
|
||||||
|
free_wallpaper_config(wc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_wallpaper_config(wallpaper_config_t *wallpaper_config) {
|
||||||
|
if (!wallpaper_config) return;
|
||||||
|
|
||||||
|
g_strfreev(wallpaper_config->path_list);
|
||||||
|
free(wallpaper_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup(void) {
|
||||||
|
clean_xcb();
|
||||||
|
|
||||||
|
free_wallpaper_config(wallpaper_config);
|
||||||
|
wallpaper_config = NULL;
|
||||||
|
|
||||||
|
monitor_t *m = monitors;
|
||||||
|
client_t *c = m->clients;
|
||||||
|
while (m) {
|
||||||
|
while (c) {
|
||||||
|
client_t *tc = c->next;
|
||||||
|
free(c);
|
||||||
|
c = tc;
|
||||||
|
}
|
||||||
|
monitor_t *tm = m->next;
|
||||||
|
free(m);
|
||||||
|
m = tm;
|
||||||
|
}
|
||||||
|
monitors = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (has_other_wm_running()) {
|
if (has_other_wm_running()) {
|
||||||
die("another window manager is already running");
|
die("another window manager is already running");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
wallpaper_config = parse_wallpaper_config(wallpager_list);
|
||||||
monitor_rect_t *mr = detect_monitor_rect();
|
if (wallpaper_config) {
|
||||||
uint32_t i = 0;
|
printf("wallpaper count: %u\n", wallpaper_config->count);
|
||||||
while (mr) {
|
for (uint32_t i = 0; i < wallpaper_config->count; i++) {
|
||||||
printf("mon[%u]: x: %d, y: %d, w: %u, h: %u\n", i, mr->x, mr->y,
|
printf("wallpaper[%02u]: %s\n", i, wallpaper_config->path_list[i]);
|
||||||
mr->width, mr->height);
|
|
||||||
mr = mr->next;
|
|
||||||
free(mr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_monitors();
|
||||||
|
|
||||||
window_list_t *window_list = scan_window_list();
|
window_list_t *window_list = scan_window_list();
|
||||||
if (window_list) {
|
if (window_list) {
|
||||||
for (uint32_t i = 0; i < window_list->count; i++) {
|
for (uint32_t i = 0; i < window_list->count; i++) {
|
||||||
@@ -31,7 +125,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
free_window_list(window_list);
|
free_window_list(window_list);
|
||||||
clean_xcb();
|
cleanup();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
void die(const char *fmt, ...) {
|
void die(const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -30,3 +32,8 @@ void *ecalloc(size_t number_of_member, size_t member_size) {
|
|||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool file_exist(const char *path) {
|
||||||
|
if (!path || !*path) return false;
|
||||||
|
return access(path, R_OK) == 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ set(LIB_XCB_NAME ${LIB_XCB} PARENT_SCOPE)
|
|||||||
|
|
||||||
add_library(${LIB_XCB} STATIC xcb.c window.c)
|
add_library(${LIB_XCB} STATIC xcb.c window.c)
|
||||||
|
|
||||||
target_include_directories(${LIB_XCB} SYSTEM PUBLIC ${XCB_INCLUDE_DIRS})
|
target_include_directories(${LIB_XCB} SYSTEM
|
||||||
target_include_directories(${LIB_XCB} PUBLIC
|
PRIVATE ${XCB_INCLUDE_DIRS}
|
||||||
"${CMAKE_SOURCE_DIR}/include"
|
)
|
||||||
"${CMAKE_BINARY_DIR}"
|
target_include_directories(${LIB_XCB}
|
||||||
|
PRIVATE "${CMAKE_SOURCE_DIR}/include"
|
||||||
|
PRIVATE "${CMAKE_BINARY_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${LIB_XCB} ${XCB_LIBRARIES})
|
target_link_libraries(${LIB_XCB}
|
||||||
|
PRIVATE ${XCB_LIBRARIES}
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user