aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-01-11 22:12:00 +0100
committerdec05eba <dec05eba@protonmail.com>2024-01-11 22:12:00 +0100
commitfb9f6797869281b1eb4f950a9b791b561e27fdd9 (patch)
treed984be918f38d48d8b0f095eccbb98b34ff294a2
parentefee05461adf85f9d2730a008c757387364deb54 (diff)
Circulate window, not perfect yet
-rw-r--r--src/compositor.c102
-rw-r--r--src/compositor.h5
-rw-r--r--src/main.c16
3 files changed, 110 insertions, 13 deletions
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: