From fb9f6797869281b1eb4f950a9b791b561e27fdd9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 11 Jan 2024 22:12:00 +0100 Subject: Circulate window, not perfect yet --- src/compositor.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++---- src/compositor.h | 5 ++- src/main.c | 16 +++++---- 3 files changed, 110 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/compositor.c b/src/compositor.c index ee6c986..133c8fc 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -32,7 +32,7 @@ void ngxc_compositor_deinit(ngxc_compositor *self) { } -void ngxc_compositor_add_window(ngxc_compositor *self, Window window) { +void ngxc_compositor_add_window(ngxc_compositor *self, Window window, Window above_window) { if(self->num_windows == NGXC_COMPOSITOR_MAX_WINDOWS) { fprintf(stderr, "error: reached max number of trackable windows (%d), ignoring window with id %ld\n", NGXC_COMPOSITOR_MAX_WINDOWS, window); return; @@ -53,23 +53,45 @@ void ngxc_compositor_add_window(ngxc_compositor *self, Window window) { return; } + window_obj->above_window = above_window; window_obj->x = xattr.x; window_obj->y = xattr.y; - ++self->num_windows; + self->num_windows++; fprintf(stderr, "ADDED WINDOW: %ld, x: %d, y: %d\n", window, xattr.x, xattr.y); } +static void ngxc_compositor_remove_window_index(ngxc_compositor *self, int window_index) { + for(int i = window_index + 1; i < self->num_windows; ++i) { + self->windows[i - 1] = self->windows[i]; + } + self->num_windows--; +} + +static void ngxc_compositor_insert_window_index(ngxc_compositor *self, const ngxc_window *window, int index) { + for(int i = self->num_windows - 1; i > index; --i) { + self->windows[i] = self->windows[i - 1]; + } + self->windows[index] = *window; +} + +static void ngxc_compositor_append_window(ngxc_compositor *self, const ngxc_window *window) { + if(self->num_windows == NGXC_COMPOSITOR_MAX_WINDOWS) { + fprintf(stderr, "error: reached max number of trackable windows (%d), ignoring window with id %ld\n", NGXC_COMPOSITOR_MAX_WINDOWS, window->texture.window); + return; + } + + self->windows[self->num_windows] = *window; + self->num_windows++; +} + void ngxc_compositor_remove_window(ngxc_compositor *self, Window window) { for(int i = 0; i < self->num_windows; ++i) { if(self->windows[i].texture.window != window) continue; window_texture_deinit(&self->windows[i].texture); - for(int j = i + 1; j < self->num_windows; ++j) { - self->windows[j - 1] = self->windows[j]; - } - self->num_windows--; + ngxc_compositor_remove_window_index(self, i); break; } } @@ -137,6 +159,52 @@ void ngxc_compositor_render(ngxc_compositor *self) { self->frame_timer = clock_get_monotonic_seconds(); } +static void ngxc_compositor_move_window_after(ngxc_compositor *self, ngxc_window *window_obj, Window above_window) { + int window_index = -1; + for(int i = 0; i < self->num_windows; ++i) { + if(self->windows[i].texture.window == window_obj->texture.window) { + window_index = i; + break; + } + } + + if(window_index == -1) { + fprintf(stderr, "error: unable to find window %ld in compositor list\n", window_obj->texture.window); + return; + } + + if(above_window == None) { + const ngxc_window window_obj_copy = *window_obj; + ngxc_compositor_remove_window_index(self, window_index); + ngxc_compositor_append_window(self, &window_obj_copy); + fprintf(stderr, "above window none, move to top\n"); + return; + } + + int above_window_index = -1; + for(int i = 0; i < self->num_windows; ++i) { + if(self->windows[i].texture.window == above_window) { + above_window_index = i; + break; + } + } + + if(above_window_index == -1) { + fprintf(stderr, "error: unable to find above window %ld in compositor list\n", above_window); + return; + } + + const ngxc_window window_obj_copy = *window_obj; + ngxc_compositor_remove_window_index(self, window_index); + if(above_window_index + 1 >= self->num_windows) { + ngxc_compositor_append_window(self, &window_obj_copy); + fprintf(stderr, "above, move to top\n"); + } else { + ngxc_compositor_insert_window_index(self, &window_obj_copy, above_window_index + 1); + fprintf(stderr, "above window after %ld\n", above_window); + } +} + void ngxc_compositor_on_configure(ngxc_compositor *self, const XConfigureEvent *configure_event) { ngxc_window *window_obj = ngxc_compositor_get_window_by_id(self, configure_event->window); if(!window_obj) @@ -148,4 +216,26 @@ void ngxc_compositor_on_configure(ngxc_compositor *self, const XConfigureEvent * if(configure_event->width != window_obj->texture.width || configure_event->height != window_obj->texture.height) { window_texture_on_resize(&window_obj->texture); } + + if(configure_event->above != window_obj->above_window && configure_event->above != window_obj->texture.window) { + window_obj->above_window = configure_event->above; // TODO: If above window is none then get the topmost window and use that + ngxc_compositor_move_window_after(self, window_obj, configure_event->above); + } +} + +void ngxc_compositor_on_circulate(ngxc_compositor *self, const XCirculateEvent *circulate_event) { + ngxc_window *window_obj = ngxc_compositor_get_window_by_id(self, circulate_event->window); + if(!window_obj) + return; + + Window above_window = None; + if(circulate_event->place == PlaceOnTop) + above_window = None; + else if(circulate_event->place == PlaceOnBottom) + above_window = self->windows[self->num_windows - 1].texture.window; + + if(above_window != window_obj->above_window && above_window != window_obj->texture.window) { + window_obj->above_window = above_window; // TODO: If above window is none then get the topmost window and use that + ngxc_compositor_move_window_after(self, window_obj, above_window); + } } diff --git a/src/compositor.h b/src/compositor.h index 3d8d876..9fe647e 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -6,8 +6,10 @@ // TODO: Make dynamic #define NGXC_COMPOSITOR_MAX_WINDOWS 100 +/* TODO: Add window index inside this struct, to know how to move this inside |ngxc_compositor.windows| */ typedef struct { WindowTexture texture; + Window above_window; int x; int y; } ngxc_window; @@ -23,9 +25,10 @@ typedef struct { void ngxc_compositor_init(ngxc_compositor *self, Display *dpy, Window composite_window); void ngxc_compositor_deinit(ngxc_compositor *self); -void ngxc_compositor_add_window(ngxc_compositor *self, Window window); +void ngxc_compositor_add_window(ngxc_compositor *self, Window window, Window above_window); void ngxc_compositor_remove_window(ngxc_compositor *self, Window window); void ngxc_compositor_render(ngxc_compositor *self); void ngxc_compositor_on_configure(ngxc_compositor *self, const XConfigureEvent *configure_event); +void ngxc_compositor_on_circulate(ngxc_compositor *self, const XCirculateEvent *circulate_event); #endif /* NGXC_COMPOSITOR_H */ diff --git a/src/main.c b/src/main.c index 7763a4b..b1c6609 100644 --- a/src/main.c +++ b/src/main.c @@ -159,7 +159,10 @@ int main(int argc, char **argv) { XQueryTree(dpy, root_window, &root_return, &parent_return, &children, &num_children); for(unsigned int i = 0; i < num_children; ++i) { - ngxc_compositor_add_window(&compositor, children[i]); + Window above_window = None; + if(i > 0) + above_window = children[i - 1]; + ngxc_compositor_add_window(&compositor, children[i], above_window); } if(children) @@ -169,11 +172,11 @@ int main(int argc, char **argv) { for(;;) { while(XPending(dpy)) { XNextEvent(dpy, &xev); - //if(xev.type != 22) - // fprintf(stderr, "event: %d\n", xev.type); + if(xev.type != 22) + fprintf(stderr, "event: %d\n", xev.type); switch(xev.type) { case CreateNotify: { - // TODO: + // TODO: Might be needed to have configure notify work with "above" field //ngxc_compositor_add_window(&compositor, xev.xcreatewindow.window); break; } @@ -183,7 +186,7 @@ int main(int argc, char **argv) { break; } case MapNotify: { - ngxc_compositor_add_window(&compositor, xev.xmap.window); + ngxc_compositor_add_window(&compositor, xev.xmap.window, None); break; } case UnmapNotify: { @@ -192,7 +195,7 @@ int main(int argc, char **argv) { } case ReparentNotify: { if(xev.xreparent.parent == root_window) - ngxc_compositor_add_window(&compositor, xev.xreparent.window); + ngxc_compositor_add_window(&compositor, xev.xreparent.window, None); else ngxc_compositor_remove_window(&compositor, xev.xreparent.window); break; @@ -204,6 +207,7 @@ int main(int argc, char **argv) { } case CirculateNotify: { fprintf(stderr, "circulate!\n"); + ngxc_compositor_on_circulate(&compositor, &xev.xcirculate); break; } default: -- cgit v1.2.3