From c4fb95cf0025b34ca14c22f4fbbfcef14d56d71c Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 11 Jan 2024 22:56:34 +0100 Subject: Proper draw order --- src/compositor.c | 70 +++++++++++++++++++++++++++----------------------------- src/compositor.h | 4 +--- src/main.c | 13 ++++------- 3 files changed, 40 insertions(+), 47 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 133c8fc..1e75d77 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -12,11 +12,14 @@ static double clock_get_monotonic_seconds(void) { return (double)ts.tv_sec + (double)ts.tv_nsec * 0.000000001; } -static ngxc_window* ngxc_compositor_get_window_by_id(ngxc_compositor *self, Window window) { +static ngxc_window* ngxc_compositor_get_window_by_id(ngxc_compositor *self, Window window, int *index) { for(int i = 0; i < self->num_windows; ++i) { ngxc_window *window_obj = &self->windows[i]; - if(window_obj->texture.window == window) + if(window_obj->texture.window == window) { + if(index) + *index = i; return window_obj; + } } return NULL; } @@ -32,7 +35,7 @@ void ngxc_compositor_deinit(ngxc_compositor *self) { } -void ngxc_compositor_add_window(ngxc_compositor *self, Window window, Window above_window) { +void ngxc_compositor_add_window(ngxc_compositor *self, 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); return; @@ -53,7 +56,6 @@ void ngxc_compositor_add_window(ngxc_compositor *self, Window window, Window abo return; } - window_obj->above_window = above_window; window_obj->x = xattr.x; window_obj->y = xattr.y; self->num_windows++; @@ -69,6 +71,12 @@ static void ngxc_compositor_remove_window_index(ngxc_compositor *self, int windo } static void ngxc_compositor_insert_window_index(ngxc_compositor *self, const ngxc_window *window, int index) { + 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->num_windows++; for(int i = self->num_windows - 1; i > index; --i) { self->windows[i] = self->windows[i - 1]; } @@ -86,13 +94,10 @@ static void ngxc_compositor_append_window(ngxc_compositor *self, const ngxc_wind } 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); - ngxc_compositor_remove_window_index(self, i); - break; + int window_index; + if(ngxc_compositor_get_window_by_id(self, window, &window_index)) { + window_texture_deinit(&self->windows[window_index].texture); + ngxc_compositor_remove_window_index(self, window_index); } } @@ -150,7 +155,7 @@ void ngxc_compositor_render(ngxc_compositor *self) { glFlush(); glFinish(); - const double time_limit = 1.0f / 60.0f; // TODO: Get from randr + const double time_limit = 1.0f / 60.0f; // TODO: Get from randr. This might not be a good way to do this when using multiple monitors with different refresh rate and opengl is synced to one monitor const double delayed_update = time_limit - frame_duration - 0.002; //fprintf(stderr, "delayed update: %f\n", delayed_update); if(delayed_update > 0.0) @@ -159,22 +164,9 @@ 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; - } - +static void ngxc_compositor_move_window_after(ngxc_compositor *self, int window_index, Window above_window) { if(above_window == None) { - const ngxc_window window_obj_copy = *window_obj; + const ngxc_window window_obj_copy = self->windows[window_index]; 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"); @@ -194,7 +186,7 @@ static void ngxc_compositor_move_window_after(ngxc_compositor *self, ngxc_window return; } - const ngxc_window window_obj_copy = *window_obj; + const ngxc_window window_obj_copy = self->windows[window_index]; ngxc_compositor_remove_window_index(self, window_index); if(above_window_index + 1 >= self->num_windows) { ngxc_compositor_append_window(self, &window_obj_copy); @@ -205,8 +197,15 @@ static void ngxc_compositor_move_window_after(ngxc_compositor *self, ngxc_window } } +static Window ngxc_compositor_get_above_window(ngxc_compositor *self, int window_index) { + if(window_index == 0) + return None; + return self->windows[window_index - 1].texture.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); + int window_index; + ngxc_window *window_obj = ngxc_compositor_get_window_by_id(self, configure_event->window, &window_index); if(!window_obj) return; @@ -217,14 +216,14 @@ void ngxc_compositor_on_configure(ngxc_compositor *self, const XConfigureEvent * 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); + if(configure_event->above != ngxc_compositor_get_above_window(self, window_index) && configure_event->above != window_obj->texture.window) { + ngxc_compositor_move_window_after(self, window_index, 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); + int window_index; + ngxc_window *window_obj = ngxc_compositor_get_window_by_id(self, circulate_event->window, &window_index); if(!window_obj) return; @@ -234,8 +233,7 @@ void ngxc_compositor_on_circulate(ngxc_compositor *self, const XCirculateEvent * 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); + if(above_window != ngxc_compositor_get_above_window(self, window_index) && above_window != window_obj->texture.window) { + ngxc_compositor_move_window_after(self, window_index, above_window); } } diff --git a/src/compositor.h b/src/compositor.h index 9fe647e..cf520d5 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -6,10 +6,8 @@ // 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; @@ -25,7 +23,7 @@ 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, Window above_window); +void ngxc_compositor_add_window(ngxc_compositor *self, Window 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); diff --git a/src/main.c b/src/main.c index b1c6609..eec03e4 100644 --- a/src/main.c +++ b/src/main.c @@ -159,10 +159,7 @@ 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) { - Window above_window = None; - if(i > 0) - above_window = children[i - 1]; - ngxc_compositor_add_window(&compositor, children[i], above_window); + ngxc_compositor_add_window(&compositor, children[i]); } if(children) @@ -172,8 +169,8 @@ 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: Might be needed to have configure notify work with "above" field @@ -186,7 +183,7 @@ int main(int argc, char **argv) { break; } case MapNotify: { - ngxc_compositor_add_window(&compositor, xev.xmap.window, None); + ngxc_compositor_add_window(&compositor, xev.xmap.window); break; } case UnmapNotify: { @@ -195,7 +192,7 @@ int main(int argc, char **argv) { } case ReparentNotify: { if(xev.xreparent.parent == root_window) - ngxc_compositor_add_window(&compositor, xev.xreparent.window, None); + ngxc_compositor_add_window(&compositor, xev.xreparent.window); else ngxc_compositor_remove_window(&compositor, xev.xreparent.window); break; -- cgit v1.2.3