Very basic native htiles

This commit is contained in:
Paul Breugnot 2024-12-29 13:51:11 +01:00
parent 000b783279
commit 9aab7c087c
10 changed files with 137 additions and 100 deletions

View File

@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 23)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -pg")
add_executable(aswm add_executable(aswm
src/aswm/aswm.c src/aswm/aswm.c
@ -16,6 +16,8 @@ add_executable(aswm
src/aswm/event_handlers/reparent.c src/aswm/event_handlers/reparent.c
src/aswm/event_handlers/destroy.c src/aswm/event_handlers/destroy.c
src/aswm/event_handlers/map.c src/aswm/event_handlers/map.c
src/aswm/event_handlers/unmap.c) src/aswm/event_handlers/unmap.c
src/aswm/log/log.c
)
target_include_directories(aswm PUBLIC ${X11_INCLUDE_DIR} src) target_include_directories(aswm PUBLIC ${X11_INCLUDE_DIR} src)
target_link_libraries(aswm ${X11_LIBRARIES}) target_link_libraries(aswm ${X11_LIBRARIES})

View File

@ -7,21 +7,19 @@
#include "event_handlers/unmap.h" #include "event_handlers/unmap.h"
#include "event_handlers/reparent.h" #include "event_handlers/reparent.h"
#include "event_handlers/destroy.h" #include "event_handlers/destroy.h"
#include "log/log.h"
Aswm _aswm; Aswm _aswm;
void aswm_open() { void aswm_open() {
_aswm.display = XOpenDisplay(NULL); _aswm.display = XOpenDisplay(NULL);
_aswm.root_window = DefaultRootWindow(_aswm.display); Window root_window = DefaultRootWindow(_aswm.display);
_aswm.root_tile = aswm_alloc_root_tile(_aswm.display, _aswm.root_window);
printf("PointerRoot %lu\n", PointerRoot); printf("PointerRoot %lu\n", PointerRoot);
printf("None %lu\n", None); printf("None %lu\n", None);
printf("Root window %lu\n", _aswm.root_window); printf("Root window %lu\n", root_window);
XSelectInput(_aswm.display, _aswm.root_window, SubstructureRedirectMask | SubstructureNotifyMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask); XSelectInput(_aswm.display, root_window, SubstructureRedirectMask | SubstructureNotifyMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask);
XSync(_aswm.display, 0); XSync(_aswm.display, 0);
atexit(aswm_close); atexit(aswm_close);
@ -41,9 +39,13 @@ void aswm_event_loop() {
break; break;
case MapRequest: case MapRequest:
OnMapRequest(&_aswm, &e.xmaprequest); OnMapRequest(&_aswm, &e.xmaprequest);
printf("Map tree:\n");
log_tree(_aswm.display, DefaultRootWindow(_aswm.display), 1);
break; break;
case UnmapNotify: case UnmapNotify:
OnUnmapNotify(&_aswm, &e.xunmap); OnUnmapNotify(&_aswm, &e.xunmap);
printf("Unmap tree:\n");
log_tree(_aswm.display, DefaultRootWindow(_aswm.display), 1);
break; break;
case DestroyNotify: case DestroyNotify:
OnDestroyNotify(&e.xdestroywindow); OnDestroyNotify(&e.xdestroywindow);
@ -81,7 +83,6 @@ void aswm_event_loop() {
} }
void aswm_close() { void aswm_close() {
aswm_free_tile(_aswm.root_tile);
XCloseDisplay(_aswm.display); XCloseDisplay(_aswm.display);
} }

View File

@ -5,8 +5,6 @@
typedef struct { typedef struct {
Display *display; Display *display;
Window root_window;
AswmTile* root_tile;
Window es_de_window; Window es_de_window;
} Aswm; } Aswm;

View File

@ -23,8 +23,7 @@ void OnMapRequest(Aswm* aswm, const XMapRequestEvent* e) {
int full_width = XDisplayWidth(e->display, screen_number); int full_width = XDisplayWidth(e->display, screen_number);
int full_height = XDisplayWidth(e->display, screen_number); int full_height = XDisplayWidth(e->display, screen_number);
aswm_map_new_window(e->display, e->window, aswm->root_tile); aswm_map_new_window(e->display, DefaultRootWindow(e->display), e->window);
/* XSelectInput(e->display, e->window, FocusChangeMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask); */ /* XSelectInput(e->display, e->window, FocusChangeMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask); */
XMapWindow(e->display, e->window);
} }

View File

@ -2,5 +2,5 @@
#include <stdio.h> #include <stdio.h>
void OnReparentNotify(const XReparentEvent* e) { void OnReparentNotify(const XReparentEvent* e) {
printf("XReparentEvent %lu\n", e->window); printf("XReparentEvent from %lu: %lu to %lu\n", e->event, e->window, e->parent);
} }

View File

@ -2,8 +2,11 @@
#include <stdio.h> #include <stdio.h>
void OnUnmapNotify(Aswm* aswm, const XUnmapEvent* e) { void OnUnmapNotify(Aswm* aswm, const XUnmapEvent* e) {
printf("XUnmapWindow %lu\n", e->window); printf("XUnmapWindow %lu tiled in %lu\n", e->window, e->event);
printf("ES-DE window %lu\n", aswm->es_de_window); printf("ES-DE window %lu\n", aswm->es_de_window);
if(aswm->es_de_window != None) if(aswm->es_de_window != None)
XSetInputFocus(e->display, aswm->es_de_window, RevertToPointerRoot, CurrentTime); XSetInputFocus(e->display, aswm->es_de_window, RevertToPointerRoot, CurrentTime);
// Since SubstructureNotify is selected on each frame, e->event corresponds
// to the parent of the unmapped window (e->window)
aswm_unmap_window(e->display, e->event);
} }

17
src/aswm/log/log.c Normal file
View File

@ -0,0 +1,17 @@
#include "log.h"
#include <stdio.h>
void log_tree(Display* display, Window window, int indent) {
for(int i = 0; i < indent; i++)
printf(" ");
printf("%lu\n", window);
Window root_window;
Window parent_tile;
Window* children;
unsigned int children_count;
XQueryTree(display, window, &root_window, &parent_tile, &children, &children_count);
for(auto i = 0; i < children_count; i++)
log_tree(display, children[i], indent+1);
XFree(children);
}

8
src/aswm/log/log.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef ASWM_LOG
#define ASWM_LOG
#include <X11/Xlib.h>
void log_tree(Display* display, Window root, int indent);
#endif

View File

@ -1,80 +1,103 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "aswm/mapper/mapper.h" #include "aswm/mapper/mapper.h"
#include "aswm/log/log.h"
AswmTile* aswm_alloc_tile() {
AswmTile* tile = malloc(sizeof(AswmTile));
for(int i = 0; i < 2; i++)
tile->children[i] = nullptr;
return tile;
}
AswmTile* aswm_alloc_root_tile(Display* display, Window window) {
int screen_number = XDefaultScreen(display);
AswmTile* tile = aswm_alloc_tile();
tile->has_children = false;
tile->x = 0;
tile->y = 0;
tile->free = true;
tile->width = XDisplayWidth(display, screen_number);
tile->height = XDisplayHeight(display, screen_number);
return tile;
}
void aswm_free_tile(AswmTile* tile) {
for(int i = 0; i < 2; i++)
aswm_free_tile(tile->children[i]);
if(tile != nullptr)
free(tile);
}
/** /**
* Returns the free tile built in the split process. * Returns the free tile built in the split process.
*/ */
AswmTile* h_split(AswmTile* tile); void h_split(Display* display, Window current_node, Window window_to_map);
AswmTile* aswm_map_new_window(Display* display, Window window, AswmTile* tile) { void aswm_map_new_window(Display* display, Window current_node, Window window_to_map) {
if(tile->has_children) { h_split(display, current_node, window_to_map);
// The tile is necessarily considered occupied
return aswm_map_new_window(display, window, tile->children[1]);
}
if(tile->free) {
// Leef of the tile tree, the window can be inserted there
tile->free = false;
tile->display = display;
tile->window = window;
// Automatically reconfigure position and size of the window
XWindowChanges changes;
changes.x = tile->x;
changes.y = tile->y;
changes.width = tile->width;
changes.height = tile->height;
XConfigureWindow(display, window, CWX | CWY | CWWidth | CWHeight, &changes);
return tile;
}
// Leef of tile tree, but occupied. Split the tile and map the window to the
// new tile.
return aswm_map_new_window(display, window, h_split(tile));
} }
AswmTile* h_split(AswmTile* tile) { void h_split(Display* display, Window current_tile, Window window_to_map) {
tile->has_children = true; // Current:
for(int i = 0; i < 2; i++) { // +--------------+
tile->children[i] = aswm_alloc_tile(); // | current tile |
tile->children[i]->has_children = false; // | +--------+ |
tile->children[i]->free = true; // | | child | |
tile->children[i]->x = tile->x; // | +--------+ |
tile->children[i]->width = tile->width; // +--------------+
tile->children[i]->height = tile->height / 2; // Target:
// +---------------+
// | current tile |
// | +-----------+ |
// | | child | |
// | +-----------+ |
// | +-----------+ |
// | | free tile | |
// | +-----------+ |
// +---------------+
XWindowAttributes current_tile_attributes;
XGetWindowAttributes(display, current_tile, &current_tile_attributes);
XReparentWindow(display, window_to_map, current_tile, 0, 0);
Window _root_window; // unused
Window _parent_window; // unused
Window* children;
unsigned int children_count;
XQueryTree(display, current_tile, &_root_window, &_parent_window, &children, &children_count);
for(auto i = 0; i < children_count; i++) {
XMoveResizeWindow(display, children[i],
0, i * current_tile_attributes.height / children_count,
current_tile_attributes.width,
current_tile_attributes.height / children_count);
} }
tile->children[0]->y = tile->y; XFree(children);
tile->children[1]->y = tile->y + tile->children[0]->height; XMapWindow(display, window_to_map);
}
aswm_map_new_window(tile->display, tile->window, tile->children[0]);
void resize_children_to_tile(Display* display, Window tile) {
return tile->children[1]; Window _root_window; // unused
Window _grand_parent; // unused
Window* children;
unsigned int children_count;
XQueryTree(
display, tile,
&_root_window, &_grand_parent,
&children, &children_count);
printf("Current siblings of %lu:\n", tile);
for(auto i = 0; i < children_count; i++)
printf("%lu ", children[i]);
printf("\n");
// Resize new children of the parent tile
XWindowAttributes parent_attributes;
XGetWindowAttributes(display, tile, &parent_attributes);
for(auto i = 0; i < children_count; i++) {
// TODO: currently only hsplit supported
XMoveResizeWindow(display, children[i],
0,
i * parent_attributes.height / children_count,
parent_attributes.width,
parent_attributes.height / children_count);
}
XFree(children);
}
void aswm_unmap_window(Display* display, Window tile) {
// +-------------------------------+
// | root |
// |+-------------+ +-------------+|
// || tile | | ||
// || +--------+ | | ||
// || | win 1 | | | ||
// || +--------+ | | ||
// || +--------+ | | ||
// || | del win| | | win 3 ||
// || +--------+ | | ||
// || +--------+ | | ||
// || | win 2 | | | ||
// || +--------+ | | ||
// |+-------------+ +-------------+|
// +-------------------------------+
resize_children_to_tile(display, tile);
} }

View File

@ -3,23 +3,9 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
struct AswmTile; Window create_aswm_root_tile(Display* display, Window root_window);
typedef struct AswmTile { void aswm_map_new_window(Display* display, Window current_node, Window window_to_map);
int x, y; void aswm_unmap_window(Display* display, Window window);
int width, height;
bool free;
Display* display;
Window window;
bool has_children;
struct AswmTile* children[2];
} AswmTile;
AswmTile* aswm_alloc_tile();
AswmTile* aswm_alloc_root_tile(Display* display, Window window);
void aswm_free_tile(AswmTile* tile);
AswmTile* aswm_map_new_window(Display* display, Window window, AswmTile* tile);
AswmTile* aswm_unmap_window(Display* display, Window window, AswmTile* tile);
#endif #endif