wh
This commit is contained in:
parent
fe17eefb21
commit
18d397b4f8
7 changed files with 202 additions and 217 deletions
|
|
@ -269,7 +269,6 @@ if(MW_USE_WAYLAND)
|
||||||
src/backend/cairo.c
|
src/backend/cairo.c
|
||||||
src/backend/wayland/wayland.c
|
src/backend/wayland/wayland.c
|
||||||
src/backend/wayland/buffer.c
|
src/backend/wayland/buffer.c
|
||||||
src/backend/wayland/hyprland.c
|
|
||||||
src/backend/wayland/interfaces.c
|
src/backend/wayland/interfaces.c
|
||||||
src/backend/wayland/region.c
|
src/backend/wayland/region.c
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -238,8 +238,6 @@ struct _MwLLWaylandTopLevel {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwLLWaylandSublevel {
|
struct _MwLLWaylandSublevel {
|
||||||
struct wl_subsurface* subsurface;
|
|
||||||
struct wl_subcompositor* subcompositor;
|
|
||||||
|
|
||||||
MwLL parent;
|
MwLL parent;
|
||||||
|
|
||||||
|
|
@ -488,8 +486,9 @@ int MwLLWaylandHyprlandGetRoundness(void);
|
||||||
|
|
||||||
void MwLLWaylandHangUntilConfigured(MwLL handle);
|
void MwLLWaylandHangUntilConfigured(MwLL handle);
|
||||||
|
|
||||||
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self);
|
// MwBool MwLLWaylandWidgetIsDestroyed(MwLL self);
|
||||||
void MwLLWaylandWidgetUndestroy(MwLL self);
|
// void MwLLWaylandWidgetUndestroy(MwLL self);
|
||||||
|
void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child));
|
||||||
|
|
||||||
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
|
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
|
||||||
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland);
|
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland);
|
||||||
|
|
@ -500,10 +499,7 @@ void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_
|
||||||
void MwLLWaylandFlush(MwLL handle);
|
void MwLLWaylandFlush(MwLL handle);
|
||||||
|
|
||||||
/* Standard procedure before event callbacks in Wayland */
|
/* Standard procedure before event callbacks in Wayland */
|
||||||
#define WAYLAND_EVENT_OP_START(self) \
|
#define WAYLAND_EVENT_OP_START(self)
|
||||||
if(MwLLWaylandWidgetIsDestroyed(self)) { \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer for WAYLAND_EVENT_OP_START */
|
/* Footer for WAYLAND_EVENT_OP_START */
|
||||||
#define WAYLAND_EVENT_OP_END(self)
|
#define WAYLAND_EVENT_OP_END(self)
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ if (grep(/^wayland$/, @backends)) {
|
||||||
new_object("src/backend/cairo.c");
|
new_object("src/backend/cairo.c");
|
||||||
new_object("src/backend/wayland/wayland.c");
|
new_object("src/backend/wayland/wayland.c");
|
||||||
new_object("src/backend/wayland/buffer.c");
|
new_object("src/backend/wayland/buffer.c");
|
||||||
new_object("src/backend/wayland/hyprland.c");
|
|
||||||
new_object("src/backend/wayland/interfaces.c");
|
new_object("src/backend/wayland/interfaces.c");
|
||||||
new_object("src/backend/wayland/region.c");
|
new_object("src/backend/wayland/region.c");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
#include <Mw/Milsko.h>
|
|
||||||
|
|
||||||
int MwLLWaylandDoRoundness(MwLL handle) {
|
|
||||||
if(handle->common.type == MwLLBackendWayland) {
|
|
||||||
return handle->wayland.on_hyprland;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
int MwLLWaylandHyprlandGetRoundness(void) {
|
|
||||||
char* home = getenv("HOME");
|
|
||||||
int fallback = 20;
|
|
||||||
char path[PATH_MAX];
|
|
||||||
int roundness = fallback;
|
|
||||||
char line[512];
|
|
||||||
FILE* f = NULL;
|
|
||||||
|
|
||||||
if(home == NULL) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/.config/hypr/hyprland.lua", home);
|
|
||||||
|
|
||||||
f = fopen(path, "r");
|
|
||||||
if(f == NULL) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(fgets(line, sizeof(line), f) != NULL) {
|
|
||||||
char* key = strstr(line, "roundness");
|
|
||||||
char* eq;
|
|
||||||
char* end;
|
|
||||||
long value;
|
|
||||||
|
|
||||||
if(key == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eq = strchr(key, '=');
|
|
||||||
if(eq == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
eq++;
|
|
||||||
|
|
||||||
while(*eq != '\0' && isspace((unsigned char)*eq)) {
|
|
||||||
eq++;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = strtol(eq, &end, 10);
|
|
||||||
if(end == eq) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
roundness = (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return roundness;
|
|
||||||
}
|
|
||||||
|
|
@ -532,7 +532,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
||||||
MwLL topmost_parent = self;
|
MwLL topmost_parent = self;
|
||||||
MwMouse p;
|
MwMouse p;
|
||||||
MwBool inArea = MwFALSE;
|
MwBool inArea = MwFALSE;
|
||||||
MwLL currentlyHeldWidget = NULL;
|
|
||||||
|
|
||||||
(void)time;
|
(void)time;
|
||||||
(void)wl_pointer;
|
(void)wl_pointer;
|
||||||
|
|
@ -540,8 +539,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
||||||
WAYLAND_EVENT_OP_START(self);
|
WAYLAND_EVENT_OP_START(self);
|
||||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||||
|
|
||||||
currentlyHeldWidget = topmost_parent->wayland.currentlyHeldWidget;
|
|
||||||
|
|
||||||
if(self->wayland.framebuffer.surface) {
|
if(self->wayland.framebuffer.surface) {
|
||||||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
inArea |= self->wayland.framebuffer.surface == curSurface;
|
||||||
}
|
}
|
||||||
|
|
@ -552,30 +549,92 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
||||||
|
|
||||||
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
|
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
|
||||||
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
|
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
|
||||||
if(currentlyHeldWidget != NULL) {
|
|
||||||
currentlyHeldWidget->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
|
|
||||||
currentlyHeldWidget->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(inArea) {
|
if(inArea) {
|
||||||
p.point = self->wayland.cur_mouse_pos;
|
p.point = self->wayland.cur_mouse_pos;
|
||||||
MwLLDispatch(self, move, &p);
|
MwLLDispatch(self, move, &p);
|
||||||
|
|
||||||
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
|
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
|
||||||
} else if(currentlyHeldWidget == self) {
|
|
||||||
p.point = currentlyHeldWidget->wayland.cur_mouse_pos;
|
|
||||||
MwLLDispatch(currentlyHeldWidget, move, &p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WAYLAND_EVENT_OP_END(self);
|
WAYLAND_EVENT_OP_END(self);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) {
|
||||||
|
// MwWidget h = (MwWidget)handle->common.user;
|
||||||
|
// MwLLDispatch(handle, down, p);
|
||||||
|
// if(h) {
|
||||||
|
// int i;
|
||||||
|
// for(i = 0; i < arrlen(h->children); i++) {
|
||||||
|
// MwLLDispatch(h->children[i]->lowlevel, down, p);
|
||||||
|
// if(arrlen(h->children[i]->children) > 0) {
|
||||||
|
// recursive_dispatch_mouse_down(h->children[i]->lowlevel, p);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
|
||||||
|
// MwWidget h = (MwWidget)handle->common.user;
|
||||||
|
// MwLLDispatch(handle, up, p);
|
||||||
|
// if(h) {
|
||||||
|
// int i;
|
||||||
|
// for(i = 0; i < arrlen(h->children); i++) {
|
||||||
|
// MwLLDispatch(h->children[i]->lowlevel, up, p);
|
||||||
|
// if(arrlen(h->children[i]->children) > 0) {
|
||||||
|
// recursive_dispatch_mouse_up(h->children[i]->lowlevel, p);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
static void pointer_iterate_master(MwLL handle, MwLL child, MwBool down) {
|
||||||
|
MwLL topmost_parent = handle;
|
||||||
|
MwPoint point;
|
||||||
|
MwPoint relative_pos;
|
||||||
|
MwPoint absolute_pos;
|
||||||
|
|
||||||
|
absolute_pos.x = child->wayland.x;
|
||||||
|
absolute_pos.y = child->wayland.y;
|
||||||
|
|
||||||
|
while(topmost_parent->wayland.parent) {
|
||||||
|
topmost_parent = topmost_parent->wayland.parent;
|
||||||
|
if(topmost_parent) {
|
||||||
|
absolute_pos.x += topmost_parent->wayland.x;
|
||||||
|
absolute_pos.y += topmost_parent->wayland.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
point = topmost_parent->wayland.cur_mouse_pos;
|
||||||
|
relative_pos.x = point.x - absolute_pos.x;
|
||||||
|
relative_pos.y = point.y - absolute_pos.y;
|
||||||
|
|
||||||
|
if(
|
||||||
|
point.x >= absolute_pos.x && point.x <= absolute_pos.x + child->wayland.ww &&
|
||||||
|
point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh) {
|
||||||
|
MwMouse p;
|
||||||
|
p.point = relative_pos;
|
||||||
|
|
||||||
|
if(down) {
|
||||||
|
MwLLDispatch(child, down, &p);
|
||||||
|
} else {
|
||||||
|
MwLLDispatch(child, up, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%p %s (%d %d %d %d)\n", child, down ? "DOWN" : "UP", p.point.x, p.point.y, child->wayland.ww, child->wayland.wh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void pointer_iterate_down(MwLL handle, MwLL child) {
|
||||||
|
pointer_iterate_master(handle, child, MwTRUE);
|
||||||
|
MwLLWaylandChildrenIterate(child, pointer_iterate_down);
|
||||||
|
}
|
||||||
|
static void pointer_iterate_up(MwLL handle, MwLL child) {
|
||||||
|
pointer_iterate_master(handle, child, MwFALSE);
|
||||||
|
MwLLWaylandChildrenIterate(child, pointer_iterate_up);
|
||||||
|
}
|
||||||
|
|
||||||
/* `wl_pointer.button` callback */
|
/* `wl_pointer.button` callback */
|
||||||
static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) {
|
static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) {
|
||||||
MwLL self = data;
|
MwLL self = data;
|
||||||
MwMouse p;
|
MwMouse p;
|
||||||
MwBool inArea = MwFALSE;
|
|
||||||
MwLL topmost_parent = self;
|
|
||||||
|
|
||||||
(void)wl_pointer;
|
(void)wl_pointer;
|
||||||
(void)serial;
|
(void)serial;
|
||||||
|
|
@ -584,15 +643,7 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
|
||||||
WAYLAND_EVENT_OP_START(self);
|
WAYLAND_EVENT_OP_START(self);
|
||||||
|
|
||||||
p.point = self->wayland.cur_mouse_pos;
|
p.point = self->wayland.cur_mouse_pos;
|
||||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
|
||||||
|
|
||||||
if(self->wayland.framebuffer.surface) {
|
|
||||||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
|
||||||
}
|
|
||||||
if(self->wayland.backbuffer.surface) {
|
|
||||||
inArea |= self->wayland.backbuffer.surface == curSurface;
|
|
||||||
}
|
|
||||||
if(inArea) {
|
|
||||||
switch(button) {
|
switch(button) {
|
||||||
case BTN_LEFT:
|
case BTN_LEFT:
|
||||||
p.button = MwMOUSE_LEFT;
|
p.button = MwMOUSE_LEFT;
|
||||||
|
|
@ -608,23 +659,14 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
|
||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||||
if(button == BTN_LEFT) {
|
|
||||||
topmost_parent->wayland.focusedWidget = self;
|
|
||||||
}
|
|
||||||
MwLLDispatch(self, down, &p);
|
MwLLDispatch(self, down, &p);
|
||||||
topmost_parent->wayland.currentlyHeldWidget = self;
|
MwLLWaylandChildrenIterate(self, pointer_iterate_down);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case WL_POINTER_BUTTON_STATE_RELEASED:
|
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||||
if(topmost_parent->wayland.currentlyHeldWidget != NULL) {
|
|
||||||
MwLLDispatch(topmost_parent->wayland.currentlyHeldWidget, up, &p);
|
|
||||||
topmost_parent->wayland.currentlyHeldWidget = NULL;
|
|
||||||
} else {
|
|
||||||
MwLLDispatch(self, up, &p);
|
MwLLDispatch(self, up, &p);
|
||||||
}
|
MwLLWaylandChildrenIterate(self, pointer_iterate_up);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(!self->wayland.has_decorations && self->wayland.do_csd) {
|
if(!self->wayland.has_decorations && self->wayland.do_csd) {
|
||||||
if(state != WL_POINTER_BUTTON_STATE_RELEASED)
|
if(state != WL_POINTER_BUTTON_STATE_RELEASED)
|
||||||
|
|
@ -1056,7 +1098,7 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
|
||||||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
||||||
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
|
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
|
||||||
} else {
|
} else {
|
||||||
wayland->sublevel->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
|
// wayland->sublevel->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1067,7 +1109,7 @@ static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, way
|
||||||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
||||||
wl_subcompositor_destroy(wayland->toplevel->scompositor);
|
wl_subcompositor_destroy(wayland->toplevel->scompositor);
|
||||||
} else {
|
} else {
|
||||||
wl_subcompositor_destroy(wayland->sublevel->subcompositor);
|
// wl_subcompositor_destroy(wayland->sublevel->subcompositor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1201,7 +1243,6 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
|
||||||
|
|
||||||
WL_INTERFACE(wl_shm);
|
WL_INTERFACE(wl_shm);
|
||||||
WL_INTERFACE(wl_compositor);
|
WL_INTERFACE(wl_compositor);
|
||||||
WL_INTERFACE(wl_seat);
|
|
||||||
WL_INTERFACE(wl_output);
|
WL_INTERFACE(wl_output);
|
||||||
WL_INTERFACE(wl_data_device_manager);
|
WL_INTERFACE(wl_data_device_manager);
|
||||||
WL_INTERFACE(zwp_primary_selection_device_manager_v1);
|
WL_INTERFACE(zwp_primary_selection_device_manager_v1);
|
||||||
|
|
@ -1214,10 +1255,14 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
|
||||||
WL_INTERFACE(zxdg_decoration_manager_v1);
|
WL_INTERFACE(zxdg_decoration_manager_v1);
|
||||||
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
|
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
|
||||||
WL_INTERFACE(wl_subcompositor);
|
WL_INTERFACE(wl_subcompositor);
|
||||||
|
WL_INTERFACE(wl_seat);
|
||||||
} else if(wayland->type == MwLL_WAYLAND_POPUP) {
|
} else if(wayland->type == MwLL_WAYLAND_POPUP) {
|
||||||
|
WL_INTERFACE(wl_seat);
|
||||||
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
|
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
|
||||||
WL_INTERFACE(wp_viewporter);
|
WL_INTERFACE(wp_viewporter);
|
||||||
WL_INTERFACE(wl_subcompositor);
|
WL_INTERFACE(wl_subcompositor);
|
||||||
|
WL_INTERFACE(wl_seat);
|
||||||
|
WL_INTERFACE(wl_seat);
|
||||||
} else {
|
} else {
|
||||||
WL_INTERFACE(wl_subcompositor);
|
WL_INTERFACE(wl_subcompositor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,37 +12,51 @@ MwBool MwWaylandVulkan = MwFALSE;
|
||||||
|
|
||||||
MwBool MwWaylandCairoOnly = MwFALSE;
|
MwBool MwWaylandCairoOnly = MwFALSE;
|
||||||
|
|
||||||
static pthread_mutex_t destroyedWidgetsTableMutex;
|
// static pthread_mutex_t destroyedWidgetsTableMutex;
|
||||||
/*
|
// /*
|
||||||
* So Wayland, bless its soul; it keeps using callbacks LONG after they should not only be destroyed but the widget doesn't even exist anymore. Naturally, this causes use after free. so we fight fire with fire in the worst code i've ever written: by storing the freed pointers here, we disallow wayland from ever using them again. if something else is created that takes this slot, we remove it from the table.
|
// * So Wayland, bless its soul; it keeps using callbacks LONG after they should not only be destroyed but the widget doesn't even exist anymore. Naturally, this causes use after free. so we fight fire with fire in the worst code i've ever written: by storing the freed pointers here, we disallow wayland from ever using them again. if something else is created that takes this slot, we remove it from the table.
|
||||||
*
|
// *
|
||||||
* To illustrate how bad this code is: if Israel and Palestine found out I was doing this then the Israel/Palestine conflict would be solved because both world leaders would come to the conclusion that this code is the worst thing ever.
|
// * To illustrate how bad this code is: if Israel and Palestine found out I was doing this then the Israel/Palestine conflict would be solved because both world leaders would come to the conclusion that this code is the worst thing ever.
|
||||||
*/
|
// */
|
||||||
static MwLL* destroyedWidgetsTable;
|
// static MwLL* destroyedWidgetsTable;
|
||||||
|
|
||||||
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self) {
|
// MwBool MwLLWaylandWidgetIsDestroyed(MwLL self) {
|
||||||
|
// int i;
|
||||||
|
// pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
||||||
|
// for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
|
||||||
|
// if(self == destroyedWidgetsTable[i]) {
|
||||||
|
// pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
||||||
|
// return MwTRUE;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
||||||
|
// return MwFALSE;
|
||||||
|
// }
|
||||||
|
// void MwLLWaylandWidgetUndestroy(MwLL self) {
|
||||||
|
// int i;
|
||||||
|
// pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
||||||
|
// for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
|
||||||
|
// if(self == destroyedWidgetsTable[i]) {
|
||||||
|
// arrdel(destroyedWidgetsTable, i);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) {
|
||||||
|
if(handle->common.user) {
|
||||||
|
MwWidget w = handle->common.user;
|
||||||
int i;
|
int i;
|
||||||
pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
for(i = 0; i < arrlen(w->children); i++) {
|
||||||
for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
|
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
||||||
if(self == destroyedWidgetsTable[i]) {
|
MwLL child = w->children[i]->lowlevel;
|
||||||
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
func(handle, child);
|
||||||
return MwTRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
|
||||||
return MwFALSE;
|
|
||||||
}
|
|
||||||
void MwLLWaylandWidgetUndestroy(MwLL self) {
|
|
||||||
int i;
|
|
||||||
pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
|
||||||
for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
|
|
||||||
if(self == destroyedWidgetsTable[i]) {
|
|
||||||
arrdel(destroyedWidgetsTable, i);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int event_loop(MwLL handle);
|
static int event_loop(MwLL handle);
|
||||||
|
|
@ -370,18 +384,6 @@ static void destroy_toplevel(MwLL r) {
|
||||||
wl_pointer_destroy(r->wayland.pointer);
|
wl_pointer_destroy(r->wayland.pointer);
|
||||||
wl_keyboard_destroy(r->wayland.keyboard);
|
wl_keyboard_destroy(r->wayland.keyboard);
|
||||||
|
|
||||||
if(r->common.user) {
|
|
||||||
MwWidget w = r->common.user;
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < arrlen(w->children); i++) {
|
|
||||||
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
|
||||||
MwLL child = w->children[i]->lowlevel;
|
|
||||||
wl_subsurface_destroy(child->wayland.sublevel->subsurface);
|
|
||||||
child->wayland.sublevel->subsurface = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||||
|
|
||||||
free(r->wayland.toplevel);
|
free(r->wayland.toplevel);
|
||||||
|
|
@ -421,22 +423,12 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
||||||
|
|
||||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
|
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
|
||||||
|
|
||||||
r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.framebuffer.surface, parent_surface);
|
|
||||||
|
|
||||||
wl_subsurface_set_desync(r->wayland.sublevel->subsurface);
|
|
||||||
wl_subsurface_set_position(r->wayland.sublevel->subsurface, x, y);
|
|
||||||
|
|
||||||
if(parent) {
|
|
||||||
wl_subsurface_place_above(r->wayland.sublevel->subsurface, parent->wayland.framebuffer.surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
|
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
|
||||||
r->wayland.xkb_state = parent->wayland.xkb_state;
|
r->wayland.xkb_state = parent->wayland.xkb_state;
|
||||||
|
|
||||||
r->wayland.configured = MwTRUE;
|
r->wayland.configured = MwTRUE;
|
||||||
|
|
||||||
MwLLWaylandFramebufferSetup(&r->wayland);
|
MwLLWaylandFramebufferSetup(&r->wayland);
|
||||||
MwLLWaylandBackbufferSetup(&r->wayland);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sublevel setup function */
|
/* Sublevel setup function */
|
||||||
|
|
@ -444,8 +436,6 @@ static void destroy_sublevel(MwLL r) {
|
||||||
MwLLWaylandBackbufferDestroy(&r->wayland);
|
MwLLWaylandBackbufferDestroy(&r->wayland);
|
||||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||||
|
|
||||||
wl_subsurface_destroy(r->wayland.sublevel->subsurface);
|
|
||||||
|
|
||||||
free(r->wayland.sublevel);
|
free(r->wayland.sublevel);
|
||||||
|
|
||||||
r->wayland.configured = MwFALSE;
|
r->wayland.configured = MwFALSE;
|
||||||
|
|
@ -873,12 +863,7 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
||||||
r->wayland.x = x;
|
r->wayland.x = x;
|
||||||
r->wayland.y = y;
|
r->wayland.y = y;
|
||||||
r->wayland.parent = parent;
|
r->wayland.parent = parent;
|
||||||
if(MwLLWaylandWidgetIsDestroyed(parent)) {
|
|
||||||
r->wayland.valid = MwFALSE;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
r->wayland.valid = MwTRUE;
|
r->wayland.valid = MwTRUE;
|
||||||
}
|
|
||||||
|
|
||||||
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
||||||
if(parent == NULL) {
|
if(parent == NULL) {
|
||||||
|
|
@ -963,10 +948,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||||
memset(r, 0, sizeof(*r));
|
memset(r, 0, sizeof(*r));
|
||||||
MwLLCreateCommon(r);
|
MwLLCreateCommon(r);
|
||||||
|
|
||||||
if(MwLLWaylandWidgetIsDestroyed(r)) {
|
|
||||||
MwLLWaylandWidgetUndestroy(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
r->wayland.is_toplevel = parent == NULL;
|
r->wayland.is_toplevel = parent == NULL;
|
||||||
r->wayland.is_clipping = 0;
|
r->wayland.is_clipping = 0;
|
||||||
|
|
||||||
|
|
@ -1030,15 +1011,11 @@ static void MwLLDestroyImpl(MwLL handle) {
|
||||||
printf("widget invalid\n");
|
printf("widget invalid\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
// pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
||||||
arrput(destroyedWidgetsTable, handle);
|
// arrput(destroyedWidgetsTable, handle);
|
||||||
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
// pthread_mutex_unlock(&destroyedWidgetsTableMutex);
|
||||||
|
|
||||||
free(handle);
|
free(handle);
|
||||||
|
|
||||||
// if(topmost_parent->wayland.currentlyHeldWidget == handle) {
|
|
||||||
// topmost_parent->wayland.currentlyHeldWidget = NULL;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
||||||
|
|
@ -1066,7 +1043,7 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
||||||
/* toplevels cannot be moved */
|
/* toplevels cannot be moved */
|
||||||
break;
|
break;
|
||||||
case MwLL_WAYLAND_SUBLEVEL:
|
case MwLL_WAYLAND_SUBLEVEL:
|
||||||
wl_subsurface_set_position(handle->wayland.sublevel->subsurface, x, y);
|
/* sublevels are drawn according to their own x/y */
|
||||||
break;
|
break;
|
||||||
case MwLL_WAYLAND_POPUP:
|
case MwLL_WAYLAND_POPUP:
|
||||||
xdg_positioner_set_anchor_rect(handle->wayland.popup->xdg_positioner, handle->wayland.parent->wayland.x, handle->wayland.parent->wayland.y, handle->wayland.ww, handle->wayland.wh);
|
xdg_positioner_set_anchor_rect(handle->wayland.popup->xdg_positioner, handle->wayland.parent->wayland.x, handle->wayland.parent->wayland.y, handle->wayland.ww, handle->wayland.wh);
|
||||||
|
|
@ -1142,6 +1119,41 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||||
|
|
||||||
handle->wayland.events_pending = 1;
|
handle->wayland.events_pending = 1;
|
||||||
}
|
}
|
||||||
|
static void draw_child(MwLL handle, MwLL child);
|
||||||
|
static void draw_children(MwLL handle);
|
||||||
|
|
||||||
|
static void draw_child(MwLL handle, MwLL child) {
|
||||||
|
cairo_t* c;
|
||||||
|
cairo_surface_t* cs;
|
||||||
|
cairo_t* selected_cairo = handle->wayland.cairo.front_cairo;
|
||||||
|
|
||||||
|
wl_surface_commit(child->wayland.framebuffer.surface);
|
||||||
|
|
||||||
|
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh);
|
||||||
|
c = cairo_create(cs);
|
||||||
|
|
||||||
|
cairo_set_source_surface(c, child->wayland.cairo.front_cs, 0, 0);
|
||||||
|
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
|
||||||
|
|
||||||
|
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_OVER);
|
||||||
|
|
||||||
|
cairo_paint(c);
|
||||||
|
|
||||||
|
cairo_set_source_surface(selected_cairo, cs, child->wayland.x, child->wayland.y);
|
||||||
|
cairo_paint(selected_cairo);
|
||||||
|
|
||||||
|
cairo_destroy(c);
|
||||||
|
cairo_surface_destroy(cs);
|
||||||
|
|
||||||
|
draw_children(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_children(MwLL handle) {
|
||||||
|
MwLLWaylandChildrenIterate(handle, draw_child);
|
||||||
|
|
||||||
|
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||||
|
handle->wayland.force_render = MwTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double r, g, b;
|
double r, g, b;
|
||||||
|
|
@ -1304,6 +1316,8 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
||||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
||||||
}
|
}
|
||||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||||
|
|
||||||
|
draw_children(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1361,10 +1375,6 @@ static int MwLLPendingImpl(MwLL handle) {
|
||||||
};
|
};
|
||||||
int pending = 0;
|
int pending = 0;
|
||||||
|
|
||||||
if(MwLLWaylandWidgetIsDestroyed(handle) || !handle->wayland.valid) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->wayland.resizing = 0;
|
handle->wayland.resizing = 0;
|
||||||
|
|
||||||
if(handle->wayland.setting_wh) {
|
if(handle->wayland.setting_wh) {
|
||||||
|
|
@ -1670,7 +1680,7 @@ static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
|
||||||
dec->decoration, toggle ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
dec->decoration, toggle ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
} else {
|
} else {
|
||||||
handle->wayland.do_csd = !toggle;
|
handle->wayland.do_csd = !toggle;
|
||||||
wl_subsurface_set_position(handle->wayland.toplevel->ssurface, handle->wayland.do_csd ? CSD_BORDER_FRAME_LEFT : 0, handle->wayland.do_csd ? CSD_BORDER_FRAME_TOP : 0);
|
// wl_subsurface_set_position(handle->wayland.toplevel->ssurface, handle->wayland.do_csd ? CSD_BORDER_FRAME_LEFT : 0, handle->wayland.do_csd ? CSD_BORDER_FRAME_TOP : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1845,20 +1855,16 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
|
||||||
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
||||||
MwLL child = w->children[i]->lowlevel;
|
MwLL child = w->children[i]->lowlevel;
|
||||||
child->wayland.sublevel->xdg_surface = handle->wayland.popup->xdg_surface;
|
child->wayland.sublevel->xdg_surface = handle->wayland.popup->xdg_surface;
|
||||||
if(child->wayland.sublevel->subsurface)
|
// if(child->wayland.sublevel->subsurface)
|
||||||
wl_subsurface_destroy(child->wayland.sublevel->subsurface);
|
// wl_subsurface_destroy(child->wayland.sublevel->subsurface);
|
||||||
MwLLWaylandFlush(handle);
|
MwLLWaylandFlush(handle);
|
||||||
|
|
||||||
child->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(child->wayland.sublevel->subcompositor, child->wayland.framebuffer.surface, handle->wayland.framebuffer.surface);
|
// child->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(child->wayland.sublevel->subcompositor, child->wayland.framebuffer.surface, handle->wayland.framebuffer.surface);
|
||||||
wl_subsurface_set_desync(child->wayland.sublevel->subsurface);
|
// wl_subsurface_set_desync(child->wayland.sublevel->subsurface);
|
||||||
wl_subsurface_set_position(child->wayland.sublevel->subsurface, child->wayland.x, child->wayland.y);
|
// wl_subsurface_set_position(child->wayland.sublevel->subsurface, child->wayland.x, child->wayland.y);
|
||||||
|
|
||||||
wl_subsurface_place_above(child->wayland.sublevel->subsurface, handle->wayland.framebuffer.surface);
|
// wl_subsurface_place_above(child->wayland.sublevel->subsurface, handle->wayland.framebuffer.surface);
|
||||||
MwLLEndStateChangeImpl(w->children[i]->lowlevel);
|
MwLLEndStateChangeImpl(w->children[i]->lowlevel);
|
||||||
|
|
||||||
if(topmost_parent) {
|
|
||||||
topmost_parent->wayland.currentlyHeldWidget = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue