🚧 Basic tiling window creation

Only supports creation of windows with horizontal splitting, and not
removal of windows.
This commit is contained in:
Paul Breugnot 2024-12-25 11:58:58 +01:00
parent 0923b1bf79
commit ac58e5e6db
8 changed files with 145 additions and 33 deletions

View File

@ -1,7 +1,9 @@
cmake_minimum_required(VERSION 3.20)
cmake_minimum_required(VERSION 3.21)
project(aswm)
set(CMAKE_C_STANDARD 23)
find_package(X11 REQUIRED)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address")
@ -9,6 +11,7 @@ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address")
add_executable(aswm
src/aswm/main.c
src/aswm/aswm.c
src/aswm/mapper/mapper.c
src/aswm/event_handlers/create.c
src/aswm/event_handlers/configure.c
src/aswm/event_handlers/reparent.c

View File

@ -1,11 +1,16 @@
#include <X11/Xlib.h>
#ifndef ASWM
#define ASWM
#include "aswm/mapper/mapper.h"
typedef struct {
Display *display;
Window root;
} aswm;
Window root_window;
AswmTile* root_tile;
} Aswm;
void AswmOpen();
void AswmEventLoop();
void AswmClose();
void aswm_open();
void aswm_event_loop();
void aswm_close();
#endif

View File

@ -1,3 +1,4 @@
#include <X11/Xlib.h>
#include "aswm/aswm.h"
void OnMapRequest(Window root, const XMapRequestEvent* e);
void OnMapRequest(Aswm* aswm, const XMapRequestEvent* e);

View File

@ -0,0 +1,24 @@
#ifndef ASWM_MAPPER
#define ASWM_MAPPER
#include <X11/Xlib.h>
struct AswmTile;
typedef struct AswmTile {
int x, y;
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);
#endif

View File

@ -1,3 +1,4 @@
#include <stdlib.h>
#include "aswm/aswm.h"
#include "aswm/event_handlers/create.h"
#include "aswm/event_handlers/configure.h"
@ -5,17 +6,22 @@
#include "aswm/event_handlers/reparent.h"
#include "aswm/event_handlers/destroy.h"
aswm _aswm;
Aswm _aswm;
void AswmOpen() {
void aswm_open() {
_aswm.display = XOpenDisplay(NULL);
_aswm.root = DefaultRootWindow(_aswm.display);
_aswm.root_window = DefaultRootWindow(_aswm.display);
XSelectInput(_aswm.display, _aswm.root, SubstructureRedirectMask | SubstructureNotifyMask);
_aswm.root_tile = aswm_alloc_root_tile(_aswm.display, _aswm.root_window);
XSelectInput(_aswm.display, _aswm.root_window, SubstructureRedirectMask | SubstructureNotifyMask);
XSync(_aswm.display, 0);
atexit(aswm_close);
}
void AswmEventLoop() {
void aswm_event_loop() {
for (;;) {
XEvent e;
XNextEvent(_aswm.display, &e);
@ -28,7 +34,7 @@ void AswmEventLoop() {
OnConfigureRequest(&e.xconfigurerequest);
break;
case MapRequest:
OnMapRequest(_aswm.root, &e.xmaprequest);
OnMapRequest(&_aswm, &e.xmaprequest);
break;
case DestroyNotify:
OnDestroyNotify(&e.xdestroywindow);
@ -43,6 +49,7 @@ void AswmEventLoop() {
}
}
void AswmClose() {
void aswm_close() {
aswm_free_tile(_aswm.root_tile);
XCloseDisplay(_aswm.display);
}

View File

@ -2,7 +2,7 @@
#include <stdio.h>
#include <X11/Xutil.h>
void OnMapRequest(Window root, const XMapRequestEvent* e) {
void OnMapRequest(Aswm* aswm, const XMapRequestEvent* e) {
printf("XMapRequestEvent %lu\n", e->window);
{
@ -20,19 +20,6 @@ void OnMapRequest(Window root, const XMapRequestEvent* e) {
int full_width = XDisplayWidth(e->display, screen_number);
int full_height = XDisplayWidth(e->display, screen_number);
// Automatically reconfigure position and size of the window
XWindowChanges changes;
changes.x = 0;
changes.y = 0;
changes.width = full_width;
changes.height = full_height;
printf("\tx = %i\n", changes.x);
printf("\ty = %i\n", changes.y);
printf("\tw = %i\n", changes.width);
printf("\th = %i\n", changes.height);
XConfigureWindow(e->display, e->window, CWX | CWY | CWWidth | CWHeight, &changes);
aswm_map_new_window(e->display, e->window, aswm->root_tile);
XMapWindow(e->display, e->window);
}

View File

@ -1,7 +1,7 @@
#include "aswm/aswm.h"
int main(int argc, char** argv) {
AswmOpen();
AswmEventLoop();
AswmClose();
aswm_open();
aswm_event_loop();
aswm_close();
}

85
src/aswm/mapper/mapper.c Normal file
View File

@ -0,0 +1,85 @@
#include <stdlib.h>
#include <stdio.h>
#include "aswm/mapper/mapper.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.
*/
AswmTile* h_split(AswmTile* tile);
AswmTile* aswm_map_new_window(Display* display, Window window, AswmTile* tile) {
if(tile->has_children) {
// 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;
printf("\tx = %i\n", changes.x);
printf("\ty = %i\n", changes.y);
printf("\tw = %i\n", changes.width);
printf("\th = %i\n", changes.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) {
tile->has_children = true;
for(int i = 0; i < 2; i++) {
tile->children[i] = aswm_alloc_tile();
tile->children[i]->has_children = false;
tile->children[i]->free = true;
tile->children[i]->x = tile->x;
tile->children[i]->width = tile->width;
tile->children[i]->height = tile->height / 2;
}
tile->children[0]->y = tile->y;
tile->children[1]->y = tile->y + tile->children[0]->height;
aswm_map_new_window(tile->display, tile->window, tile->children[0]);
return tile->children[1];
}