Compare commits
8 commits
master
...
wl_removel
| Author | SHA1 | Date | |
|---|---|---|---|
| 0181a61a3d | |||
| 4c331ad2da | |||
| 6e2b0ff097 | |||
| 7aad2af609 | |||
| 70147b2716 | |||
| ad7db9dcec | |||
| 8fe9a1c168 | |||
| 14915e082a |
5 changed files with 223 additions and 223 deletions
|
|
@ -14,7 +14,13 @@
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <dbus/dbus.h>
|
/* libdecor is included later on so that it's covered by the wayland dynloading. */
|
||||||
|
struct libdecor_frame;
|
||||||
|
struct libdecor_interface;
|
||||||
|
struct libdecor_configuration;
|
||||||
|
struct libdecor_frame_interface;
|
||||||
|
enum libdecor_window_state;
|
||||||
|
struct wl_surface;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -44,6 +50,8 @@ typedef struct wayland_call_table {
|
||||||
void* lib;
|
void* lib;
|
||||||
void* xkb_lib;
|
void* xkb_lib;
|
||||||
void* cairo_lib;
|
void* cairo_lib;
|
||||||
|
|
||||||
|
void* libdecor_lib;
|
||||||
#ifdef USE_DBUS
|
#ifdef USE_DBUS
|
||||||
MwLLDBusFuncTable dbus;
|
MwLLDBusFuncTable dbus;
|
||||||
MwBool has_dbus;
|
MwBool has_dbus;
|
||||||
|
|
@ -141,6 +149,20 @@ typedef struct wayland_call_table {
|
||||||
void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t);
|
void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t);
|
||||||
void (*cairo_set_operator)(cairo_t* cr, cairo_operator_t op);
|
void (*cairo_set_operator)(cairo_t* cr, cairo_operator_t op);
|
||||||
|
|
||||||
|
MwBool has_libdecor;
|
||||||
|
struct libdecor* (*libdecor_new)(struct wl_display* display, struct libdecor_interface* iface);
|
||||||
|
struct libdecor_state* (*libdecor_state_new)(int width, int height);
|
||||||
|
void (*libdecor_frame_commit)(struct libdecor_frame* frame, struct libdecor_state* state, struct libdecor_configuration* configuration);
|
||||||
|
void (*libdecor_state_free)(struct libdecor_state* state);
|
||||||
|
struct libdecor_frame* (*libdecor_decorate)(struct libdecor* context, struct wl_surface* surface, struct libdecor_frame_interface* iface, void* user_data);
|
||||||
|
void (*libdecor_frame_set_app_id)(struct libdecor_frame* frame, const char* app_id);
|
||||||
|
void (*libdecor_frame_set_title)(struct libdecor_frame* frame, const char* title);
|
||||||
|
void (*libdecor_frame_map)(struct libdecor_frame* frame);
|
||||||
|
MwBool (*libdecor_configuration_get_content_size)(struct libdecor_configuration* configuration, struct libdecor_frame* frame, int* width, int* height);
|
||||||
|
MwBool (*libdecor_configuration_get_window_state)(struct libdecor_configuration* configuration, enum libdecor_window_state* window_state);
|
||||||
|
struct xdg_surface* (*libdecor_frame_get_xdg_surface)(struct libdecor_frame* frame);
|
||||||
|
int (*libdecor_dispatch)(struct libdecor* context, int timeout);
|
||||||
|
void (*libdecor_frame_translate_coordinate)(struct libdecor_frame* frame, int surface_x, int surface_y, int* frame_x, int* frame_y);
|
||||||
} wayland_call_table_t;
|
} wayland_call_table_t;
|
||||||
|
|
||||||
extern wayland_call_table_t wl_call_tbl;
|
extern wayland_call_table_t wl_call_tbl;
|
||||||
|
|
@ -186,6 +208,17 @@ MwInline int wayland_load_funcs() {
|
||||||
return 1; \
|
return 1; \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* i mean i pray if somebody is using thr wayland backend over apple/ios that actual decorations are supported. */
|
||||||
|
#ifdef __APPLE__
|
||||||
|
wl_call_tbl.libdecor_lib = MwDynamicOpen("libdecor-0.dylib");
|
||||||
|
#else
|
||||||
|
wl_call_tbl.libdecor_lib = MwDynamicOpen("libdecor-0.so");
|
||||||
|
#endif
|
||||||
|
wl_call_tbl.has_libdecor = (wl_call_tbl.libdecor_lib != NULL);
|
||||||
|
if(!wl_call_tbl.libdecor_lib) {
|
||||||
|
printf("(libdecor not found, window will not have any decorations.)\n");
|
||||||
|
}
|
||||||
|
|
||||||
WAYLAND_FUNC(wl_display_dispatch)
|
WAYLAND_FUNC(wl_display_dispatch)
|
||||||
WAYLAND_FUNC(wl_display_dispatch_pending)
|
WAYLAND_FUNC(wl_display_dispatch_pending)
|
||||||
WAYLAND_FUNC(wl_display_disconnect)
|
WAYLAND_FUNC(wl_display_disconnect)
|
||||||
|
|
@ -267,6 +300,28 @@ MwInline int wayland_load_funcs() {
|
||||||
wl_call_tbl.has_dbus = MwLLDBusFuncSetup(&wl_call_tbl.dbus);
|
wl_call_tbl.has_dbus = MwLLDBusFuncSetup(&wl_call_tbl.dbus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(wl_call_tbl.has_libdecor) {
|
||||||
|
#define LIBDECOR_FUNC(x) \
|
||||||
|
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.libdecor_lib, #x); \
|
||||||
|
if(!wl_call_tbl.x) { \
|
||||||
|
printf("WARNING: Can't use libdecor because libdecor-1 doesn't export " #x ".\n"); \
|
||||||
|
wl_call_tbl.has_libdecor = MwFALSE; \
|
||||||
|
};
|
||||||
|
|
||||||
|
LIBDECOR_FUNC(libdecor_new);
|
||||||
|
LIBDECOR_FUNC(libdecor_state_new);
|
||||||
|
LIBDECOR_FUNC(libdecor_frame_commit);
|
||||||
|
LIBDECOR_FUNC(libdecor_state_free);
|
||||||
|
LIBDECOR_FUNC(libdecor_decorate);
|
||||||
|
LIBDECOR_FUNC(libdecor_frame_set_app_id);
|
||||||
|
LIBDECOR_FUNC(libdecor_frame_set_title);
|
||||||
|
LIBDECOR_FUNC(libdecor_frame_map);
|
||||||
|
LIBDECOR_FUNC(libdecor_configuration_get_content_size);
|
||||||
|
LIBDECOR_FUNC(libdecor_configuration_get_window_state);
|
||||||
|
LIBDECOR_FUNC(libdecor_frame_get_xdg_surface);
|
||||||
|
LIBDECOR_FUNC(libdecor_dispatch);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,6 +397,8 @@ MwInline int wayland_load_funcs() {
|
||||||
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
|
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <libdecor.h>
|
||||||
|
|
||||||
typedef struct wayland_protocol {
|
typedef struct wayland_protocol {
|
||||||
void* listener;
|
void* listener;
|
||||||
void* context;
|
void* context;
|
||||||
|
|
@ -495,6 +552,11 @@ struct _MwLLWayland {
|
||||||
MwLLDBusContext dbus;
|
MwLLDBusContext dbus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct libdecor* decor;
|
||||||
|
struct libdecor_frame* decor_frame;
|
||||||
|
struct libdecor_interface* decor_interface;
|
||||||
|
enum libdecor_window_state decor_state;
|
||||||
|
|
||||||
MwBool dark_theme_detection;
|
MwBool dark_theme_detection;
|
||||||
MwU32 dark_theme;
|
MwU32 dark_theme;
|
||||||
|
|
||||||
|
|
@ -568,8 +630,6 @@ struct _MwLLWayland {
|
||||||
cairo_surface_t* back_cs;
|
cairo_surface_t* back_cs;
|
||||||
cairo_t* front_cairo;
|
cairo_t* front_cairo;
|
||||||
cairo_t* back_cairo;
|
cairo_t* back_cairo;
|
||||||
/* The cairo to actually use for draw operations. Typically is front_cairo, but MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
|
|
||||||
cairo_t* selected_cairo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwLLWaylandColor {
|
struct _MwLLWaylandColor {
|
||||||
|
|
@ -601,9 +661,6 @@ void MwLLWaylandRegionInvalidate(MwLL handle);
|
||||||
|
|
||||||
void MwLLWaylandHangUntilConfigured(MwLL handle);
|
void MwLLWaylandHangUntilConfigured(MwLL handle);
|
||||||
|
|
||||||
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self);
|
|
||||||
void MwLLWaylandWidgetUndestroy(MwLL self);
|
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
|
|
@ -613,19 +670,11 @@ 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)
|
||||||
|
|
||||||
#define WIDGET_CHECK(handle) \
|
|
||||||
if(!handle->wayland.valid) { \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the two decoration manager constructs */
|
/* the two decoration manager constructs */
|
||||||
typedef struct zxdg_decoration_manager_v1_context {
|
typedef struct zxdg_decoration_manager_v1_context {
|
||||||
struct zxdg_decoration_manager_v1* manager;
|
struct zxdg_decoration_manager_v1* manager;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ my @enabled_backends = ();
|
||||||
|
|
||||||
if (param_get("wayland") && not(param_get("tiny"))) {
|
if (param_get("wayland") && not(param_get("tiny"))) {
|
||||||
push(@enabled_backends, "wayland");
|
push(@enabled_backends, "wayland");
|
||||||
|
add_cflags(`pkg-config --cflags libdecor-0`);
|
||||||
}
|
}
|
||||||
if (param_get("x11")) {
|
if (param_get("x11")) {
|
||||||
push(@enabled_backends, "x11");
|
push(@enabled_backends, "x11");
|
||||||
|
|
@ -9,6 +10,7 @@ if (param_get("x11")) {
|
||||||
|
|
||||||
add_cflags("-DUSE_DBUS");
|
add_cflags("-DUSE_DBUS");
|
||||||
|
|
||||||
|
|
||||||
use_backend(@enabled_backends);
|
use_backend(@enabled_backends);
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
||||||
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
|
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
|
||||||
wl_surface_commit(wayland->framebuffer.surface);
|
wl_surface_commit(wayland->framebuffer.surface);
|
||||||
|
|
||||||
MwLLWaylandHangUntilConfigured((MwLL)wayland);
|
// MwLLWaylandHangUntilConfigured((MwLL)wayland);
|
||||||
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer);
|
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer);
|
||||||
};
|
};
|
||||||
void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* wayland) {
|
void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* wayland) {
|
||||||
|
|
|
||||||
|
|
@ -10,39 +10,6 @@ wayland_call_table_t wl_call_tbl;
|
||||||
MwBool MwWaylandVulkan = MwFALSE;
|
MwBool MwWaylandVulkan = MwFALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* TODO(IOI): FUCKING NO???? FIX THIS.
|
|
||||||
*/
|
|
||||||
static MwLL* destroyedWidgetsTable;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int event_loop(MwLL handle);
|
static int event_loop(MwLL handle);
|
||||||
|
|
||||||
/* Recursively dispatch a resize event to a widget and its children */
|
/* Recursively dispatch a resize event to a widget and its children */
|
||||||
|
|
@ -61,7 +28,6 @@ static void recursive_dispatch_resize(MwLL handle) {
|
||||||
|
|
||||||
static void recursive_render(MwLL handle) {
|
static void recursive_render(MwLL handle) {
|
||||||
int i;
|
int i;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
for(i = 0; i < arrlen(((MwWidget)handle->common.user)->children); i++) recursive_render(((MwWidget)handle->common.user)->children[i]->lowlevel);
|
for(i = 0; i < arrlen(((MwWidget)handle->common.user)->children); i++) recursive_render(((MwWidget)handle->common.user)->children[i]->lowlevel);
|
||||||
|
|
||||||
|
|
@ -235,6 +201,96 @@ void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* shitdecor */
|
||||||
|
static void libdecor_error(struct libdecor* context,
|
||||||
|
enum libdecor_error error,
|
||||||
|
const char* message) {
|
||||||
|
printf("libdecor error (%d): %s\n", error, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_configure(struct libdecor_frame* frame,
|
||||||
|
struct libdecor_configuration* configuration,
|
||||||
|
void* user_data) {
|
||||||
|
MwLL self = user_data;
|
||||||
|
int width, height;
|
||||||
|
enum libdecor_window_state window_state;
|
||||||
|
struct libdecor_state* state;
|
||||||
|
|
||||||
|
if(!wl_call_tbl.libdecor_configuration_get_content_size(configuration, frame,
|
||||||
|
&width, &height)) {
|
||||||
|
width = self->wayland.ww;
|
||||||
|
height = self->wayland.wh;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = (width == 0) ? 1 : width;
|
||||||
|
height = (height == 0) ? 1 : height;
|
||||||
|
|
||||||
|
// region_invalidate(self);
|
||||||
|
self->wayland.ww = width;
|
||||||
|
self->wayland.wh = height;
|
||||||
|
|
||||||
|
if(self->wayland.resizing == 0) {
|
||||||
|
MwLLWaylandFramebufferDestroy(&self->wayland);
|
||||||
|
MwLLWaylandFramebufferSetup(&self->wayland);
|
||||||
|
MwLLWaylandRegionSetup(self);
|
||||||
|
MwLLDispatch(self, resize, NULL);
|
||||||
|
|
||||||
|
recursive_dispatch_resize(self);
|
||||||
|
|
||||||
|
if(self->wayland.pointer_constrained) {
|
||||||
|
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
|
||||||
|
wl_surface_commit(self->wayland.framebuffer.surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->wayland.resizing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MwLLDispatch(self, draw, NULL);
|
||||||
|
|
||||||
|
if(!wl_call_tbl.libdecor_configuration_get_window_state(configuration,
|
||||||
|
&window_state))
|
||||||
|
window_state = LIBDECOR_WINDOW_STATE_NONE;
|
||||||
|
|
||||||
|
self->wayland.decor_state = window_state;
|
||||||
|
|
||||||
|
state = wl_call_tbl.libdecor_state_new(width, height);
|
||||||
|
wl_call_tbl.libdecor_frame_commit(frame, state, configuration);
|
||||||
|
wl_call_tbl.libdecor_state_free(state);
|
||||||
|
|
||||||
|
self->wayland.configured = MwTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_close(struct libdecor_frame* frame,
|
||||||
|
void* user_data) {
|
||||||
|
MwLL self = user_data;
|
||||||
|
MwLLDispatch(self, close, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_commit(struct libdecor_frame* frame,
|
||||||
|
void* user_data) {
|
||||||
|
MwLL self = user_data;
|
||||||
|
wl_surface_commit(self->wayland.framebuffer.surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_dismiss_popup(struct libdecor_frame* frame,
|
||||||
|
const char* seat_name,
|
||||||
|
void* user_data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct libdecor_frame_interface libdecor_frame_iface = {
|
||||||
|
handle_configure,
|
||||||
|
handle_close,
|
||||||
|
handle_commit,
|
||||||
|
handle_dismiss_popup,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct libdecor_interface libdecor_interface = {
|
||||||
|
libdecor_error};
|
||||||
|
|
||||||
/* Toplevel setup function */
|
/* Toplevel setup function */
|
||||||
static void setup_toplevel(MwLL r, int x, int y) {
|
static void setup_toplevel(MwLL r, int x, int y) {
|
||||||
r->wayland.type = MwLL_WAYLAND_TOPLEVEL;
|
r->wayland.type = MwLL_WAYLAND_TOPLEVEL;
|
||||||
|
|
@ -268,15 +324,14 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
||||||
|
|
||||||
r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
|
||||||
/* Create a wl_surface, a xdg_surface and a xdg_toplevel */
|
|
||||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||||
r->wayland.backbuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
r->wayland.backbuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||||
r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface);
|
|
||||||
wl_subsurface_set_desync(r->wayland.toplevel->ssurface);
|
|
||||||
|
|
||||||
r->wayland.toplevel->xdg_surface =
|
if(r->wayland.has_decorations) {
|
||||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface);
|
r->wayland.toplevel->xdg_surface =
|
||||||
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
||||||
|
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
||||||
|
}
|
||||||
|
|
||||||
/* setup mandatory listeners */
|
/* setup mandatory listeners */
|
||||||
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
||||||
|
|
@ -284,16 +339,26 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
||||||
r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure;
|
r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure;
|
||||||
r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close;
|
r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close;
|
||||||
|
|
||||||
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
if(r->wayland.has_decorations) {
|
||||||
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
||||||
r);
|
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
||||||
|
r);
|
||||||
|
|
||||||
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko App");
|
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko App");
|
||||||
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
||||||
|
} else {
|
||||||
|
r->wayland.decor = wl_call_tbl.libdecor_new(r->wayland.display, &libdecor_interface);
|
||||||
|
r->wayland.decor_frame = wl_call_tbl.libdecor_decorate(r->wayland.decor, r->wayland.framebuffer.surface,
|
||||||
|
&libdecor_frame_iface, r);
|
||||||
|
wl_call_tbl.libdecor_frame_set_app_id(r->wayland.decor_frame, "milsko-app");
|
||||||
|
wl_call_tbl.libdecor_frame_set_title(r->wayland.decor_frame, "Milsko App");
|
||||||
|
wl_call_tbl.libdecor_frame_map(r->wayland.decor_frame);
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform the initial commit and wait for the first configure event */
|
/* Perform the initial commit and wait for the first configure event */
|
||||||
wl_surface_commit(r->wayland.backbuffer.surface);
|
|
||||||
wl_surface_commit(r->wayland.framebuffer.surface);
|
wl_surface_commit(r->wayland.framebuffer.surface);
|
||||||
|
wl_surface_commit(r->wayland.backbuffer.surface);
|
||||||
|
|
||||||
while(!r->wayland.configured) {
|
while(!r->wayland.configured) {
|
||||||
event_loop(r);
|
event_loop(r);
|
||||||
}
|
}
|
||||||
|
|
@ -307,8 +372,6 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
||||||
|
|
||||||
zxdg_toplevel_decoration_v1_set_mode(
|
zxdg_toplevel_decoration_v1_set_mode(
|
||||||
dec->decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
dec->decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
} else {
|
|
||||||
wl_subsurface_set_position(r->wayland.toplevel->ssurface, CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_TOP);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,9 +386,10 @@ static void destroy_toplevel(MwLL r) {
|
||||||
|
|
||||||
wl_compositor_destroy(r->wayland.compositor);
|
wl_compositor_destroy(r->wayland.compositor);
|
||||||
|
|
||||||
xdg_surface_destroy(r->wayland.toplevel->xdg_surface);
|
if(r->wayland.has_decorations) {
|
||||||
|
xdg_surface_destroy(r->wayland.toplevel->xdg_surface);
|
||||||
xdg_toplevel_destroy(r->wayland.toplevel->xdg_top_level);
|
xdg_toplevel_destroy(r->wayland.toplevel->xdg_top_level);
|
||||||
|
}
|
||||||
|
|
||||||
xkb_keymap_unref(r->wayland.xkb_keymap);
|
xkb_keymap_unref(r->wayland.xkb_keymap);
|
||||||
|
|
||||||
|
|
@ -440,6 +504,7 @@ struct xdg_popup_listener popup_listener = {
|
||||||
/* Popup setup function */
|
/* Popup setup function */
|
||||||
static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
||||||
struct xdg_surface* xdg_surface;
|
struct xdg_surface* xdg_surface;
|
||||||
|
struct xdg_surface* parent_xdg_surface;
|
||||||
MwLL topmost_parent = r->wayland.parent;
|
MwLL topmost_parent = r->wayland.parent;
|
||||||
|
|
||||||
r->wayland.type = MwLL_WAYLAND_POPUP;
|
r->wayland.type = MwLL_WAYLAND_POPUP;
|
||||||
|
|
@ -489,16 +554,20 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
||||||
|
|
||||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||||
|
|
||||||
|
if(r->wayland.has_decorations) {
|
||||||
|
parent_xdg_surface = topmost_parent->wayland.toplevel->xdg_surface;
|
||||||
|
} else {
|
||||||
|
parent_xdg_surface = wl_call_tbl.libdecor_frame_get_xdg_surface(topmost_parent->wayland.decor_frame);
|
||||||
|
}
|
||||||
|
|
||||||
r->wayland.popup->xdg_surface =
|
r->wayland.popup->xdg_surface =
|
||||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
||||||
|
|
||||||
r->wayland.popup->xdg_popup = xdg_surface_get_popup(
|
r->wayland.popup->xdg_popup = xdg_surface_get_popup(
|
||||||
r->wayland.popup->xdg_surface,
|
r->wayland.popup->xdg_surface,
|
||||||
xdg_surface,
|
parent_xdg_surface,
|
||||||
r->wayland.popup->xdg_positioner);
|
r->wayland.popup->xdg_positioner);
|
||||||
|
|
||||||
uint32_t ver = wl_proxy_get_version((struct wl_proxy*)r->wayland.popup->xdg_popup);
|
|
||||||
|
|
||||||
xdg_popup_add_listener(r->wayland.popup->xdg_popup, &popup_listener, r);
|
xdg_popup_add_listener(r->wayland.popup->xdg_popup, &popup_listener, r);
|
||||||
|
|
||||||
r->wayland.popup->xdg_surface_listener.configure = xdg_surface_configure;
|
r->wayland.popup->xdg_surface_listener.configure = xdg_surface_configure;
|
||||||
|
|
@ -628,12 +697,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 = MwTRUE;
|
||||||
r->wayland.valid = MwFALSE;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
r->wayland.valid = MwTRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
||||||
if(parent == NULL) {
|
if(parent == NULL) {
|
||||||
|
|
@ -657,8 +721,6 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WIDGET_CHECK(r);
|
|
||||||
|
|
||||||
MwLLWaylandFramebufferSetup(&r->wayland);
|
MwLLWaylandFramebufferSetup(&r->wayland);
|
||||||
MwLLWaylandBackbufferSetup(&r->wayland);
|
MwLLWaylandBackbufferSetup(&r->wayland);
|
||||||
|
|
||||||
|
|
@ -702,10 +764,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;
|
||||||
|
|
||||||
|
|
@ -786,15 +844,7 @@ static void MwLLDestroyImpl(MwLL handle) {
|
||||||
|
|
||||||
MwLLWaylandFlush(handle);
|
MwLLWaylandFlush(handle);
|
||||||
|
|
||||||
pthread_mutex_lock(&destroyedWidgetsTableMutex);
|
|
||||||
arrput(destroyedWidgetsTable, handle);
|
|
||||||
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) {
|
||||||
|
|
@ -812,7 +862,6 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
MwLLWaylandRegionInvalidate(handle);
|
MwLLWaylandRegionInvalidate(handle);
|
||||||
handle->wayland.x = x;
|
handle->wayland.x = x;
|
||||||
handle->wayland.y = y;
|
handle->wayland.y = y;
|
||||||
|
|
@ -837,7 +886,11 @@ static void actually_set_wh(MwLL handle) {
|
||||||
MwLLWaylandRegionInvalidate(handle);
|
MwLLWaylandRegionInvalidate(handle);
|
||||||
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL && handle->wayland.configured) {
|
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL && handle->wayland.configured) {
|
||||||
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
if(handle->wayland.has_decorations) {
|
||||||
|
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||||
|
} else {
|
||||||
|
xdg_surface_set_window_geometry(wl_call_tbl.libdecor_frame_get_xdg_surface(handle->wayland.decor_frame), 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && handle->wayland.configured && !handle->wayland.dispatching_resize) {
|
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && handle->wayland.configured && !handle->wayland.dispatching_resize) {
|
||||||
|
|
@ -863,7 +916,6 @@ static void actually_set_wh(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
if(handle->wayland.ww == w && handle->wayland.wh == h) {
|
if(handle->wayland.ww == w && handle->wayland.wh == h) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -886,102 +938,6 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLBeginDrawImpl(MwLL handle) {
|
static void MwLLBeginDrawImpl(MwLL handle) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
cairo_save(handle->wayland.front_cairo);
|
|
||||||
cairo_set_source_rgba(handle->wayland.front_cairo, 0, 0, 0, 0);
|
|
||||||
cairo_set_operator(handle->wayland.front_cairo, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_rectangle(handle->wayland.front_cairo, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
|
||||||
cairo_fill(handle->wayland.front_cairo);
|
|
||||||
cairo_restore(handle->wayland.front_cairo);
|
|
||||||
|
|
||||||
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
|
||||||
handle->wayland.selected_cairo = handle->wayland.front_cairo;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!handle->wayland.has_decorations) {
|
|
||||||
int x;
|
|
||||||
MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
|
|
||||||
MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
|
|
||||||
cairo_set_line_width(handle->wayland.back_cairo, 4.0);
|
|
||||||
for(x = 0; x < w; x++) {
|
|
||||||
float placeholder = (float)x / (float)w;
|
|
||||||
cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25);
|
|
||||||
|
|
||||||
cairo_move_to(handle->wayland.back_cairo, w - x, 0);
|
|
||||||
cairo_line_to(handle->wayland.back_cairo, w - x, CSD_BORDER_FRAME_TOP);
|
|
||||||
cairo_stroke(handle->wayland.back_cairo);
|
|
||||||
|
|
||||||
cairo_move_to(handle->wayland.back_cairo, x, CSD_BORDER_FRAME_TOP);
|
|
||||||
cairo_line_to(handle->wayland.back_cairo, x, h);
|
|
||||||
cairo_stroke(handle->wayland.back_cairo);
|
|
||||||
}
|
|
||||||
cairo_set_source_rgba(handle->wayland.back_cairo, 1, 1, 1, 0.5);
|
|
||||||
cairo_move_to(handle->wayland.back_cairo, 0, 0);
|
|
||||||
cairo_line_to(handle->wayland.back_cairo, 0, h);
|
|
||||||
cairo_stroke(handle->wayland.back_cairo);
|
|
||||||
cairo_move_to(handle->wayland.back_cairo, 0, 0);
|
|
||||||
cairo_line_to(handle->wayland.back_cairo, w, 0);
|
|
||||||
cairo_stroke(handle->wayland.back_cairo);
|
|
||||||
|
|
||||||
cairo_set_source_rgba(handle->wayland.back_cairo, 0, 0, 0, 0.5);
|
|
||||||
cairo_move_to(handle->wayland.back_cairo, 0, h);
|
|
||||||
cairo_line_to(handle->wayland.back_cairo, w, h);
|
|
||||||
cairo_stroke(handle->wayland.back_cairo);
|
|
||||||
cairo_move_to(handle->wayland.back_cairo, w, 0);
|
|
||||||
cairo_line_to(handle->wayland.back_cairo, w, h);
|
|
||||||
cairo_stroke(handle->wayland.back_cairo);
|
|
||||||
|
|
||||||
if(strlen(handle->wayland.title) != 0) {
|
|
||||||
int y, x;
|
|
||||||
int i = 0, sx = 0, sy = 0;
|
|
||||||
int tw, th;
|
|
||||||
unsigned char* px;
|
|
||||||
MwRect r;
|
|
||||||
MwLLPixmap p;
|
|
||||||
tw = strlen(handle->wayland.title) * 7;
|
|
||||||
th = 14;
|
|
||||||
px = malloc(tw * th * 4);
|
|
||||||
assert(px);
|
|
||||||
|
|
||||||
memset(px, 0, tw * th * 4);
|
|
||||||
|
|
||||||
handle->wayland.selected_cairo = handle->wayland.back_cairo;
|
|
||||||
|
|
||||||
while(handle->wayland.title[i]) {
|
|
||||||
int out;
|
|
||||||
i += MwUTF8ToUTF32(handle->wayland.title + i, &out);
|
|
||||||
|
|
||||||
if(out > 0xff) {
|
|
||||||
out = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(y = 0; y < 14; y++) {
|
|
||||||
for(x = 0; x < 7; x++) {
|
|
||||||
unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4];
|
|
||||||
int col = MwFontData[out].data[y] & (1 << ((7 - 1) - x)) ? 255 : 0;
|
|
||||||
ppx[0] = col;
|
|
||||||
ppx[1] = col;
|
|
||||||
ppx[2] = col;
|
|
||||||
ppx[3] = col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sx += 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = MwLLCreatePixmap(handle, px, tw, th);
|
|
||||||
r.x = 5;
|
|
||||||
r.y = 5;
|
|
||||||
r.width = tw;
|
|
||||||
r.height = th;
|
|
||||||
|
|
||||||
MwLLDrawPixmap(handle, &r, p);
|
|
||||||
MwLLDestroyPixmap(p);
|
|
||||||
free(px);
|
|
||||||
}
|
|
||||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
|
||||||
}
|
|
||||||
handle->wayland.selected_cairo = handle->wayland.front_cairo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLEndDrawImpl(MwLL handle) {
|
static void MwLLEndDrawImpl(MwLL handle) {
|
||||||
|
|
@ -995,7 +951,6 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
||||||
|
|
||||||
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||||
int i;
|
int i;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
clip(handle);
|
clip(handle);
|
||||||
|
|
||||||
|
|
@ -1019,7 +974,6 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
|
||||||
|
|
||||||
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
||||||
int i;
|
int i;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
clip(handle);
|
clip(handle);
|
||||||
|
|
||||||
|
|
@ -1073,10 +1027,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) {
|
||||||
|
|
@ -1128,7 +1078,6 @@ static int MwLLPendingImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLNextEventImpl(MwLL handle) {
|
static void MwLLNextEventImpl(MwLL handle) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
if(!MwWaylandVulkan) {
|
if(!MwWaylandVulkan) {
|
||||||
if(handle->wayland.did_event_loop_early) {
|
if(handle->wayland.did_event_loop_early) {
|
||||||
handle->wayland.did_event_loop_early = MwFALSE;
|
handle->wayland.did_event_loop_early = MwFALSE;
|
||||||
|
|
@ -1137,6 +1086,10 @@ static void MwLLNextEventImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(handle->wayland.decor) {
|
||||||
|
// wl_call_tbl.libdecor_dispatch(handle->wayland.decor, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if(handle->wayland.force_render) {
|
if(handle->wayland.force_render) {
|
||||||
MwLLDispatch(handle, draw, NULL);
|
MwLLDispatch(handle, draw, NULL);
|
||||||
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||||
|
|
@ -1148,9 +1101,12 @@ static void MwLLNextEventImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
|
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||||
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
|
if(handle->wayland.has_decorations) {
|
||||||
|
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
|
||||||
|
} else {
|
||||||
|
wl_call_tbl.libdecor_frame_set_title(handle->wayland.decor_frame, title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!handle->wayland.has_decorations) {
|
if(!handle->wayland.has_decorations) {
|
||||||
strncpy(handle->wayland.title, title, 255);
|
strncpy(handle->wayland.title, title, 255);
|
||||||
|
|
@ -1207,14 +1163,11 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
|
||||||
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||||
cairo_t* c;
|
cairo_t* c;
|
||||||
cairo_surface_t* cs;
|
cairo_surface_t* cs;
|
||||||
cairo_t* selected_cairo = handle->wayland.selected_cairo ? handle->wayland.selected_cairo : handle->wayland.front_cairo;
|
|
||||||
|
|
||||||
if(rect->width <= 0 || rect->height <= 0 || pixmap->common.width <= 0 || pixmap->common.height <= 0) return;
|
if(rect->width <= 0 || rect->height <= 0 || pixmap->common.width <= 0 || pixmap->common.height <= 0) return;
|
||||||
if(rect->width >= INT16_MAX) rect->width = INT16_MAX;
|
if(rect->width >= INT16_MAX) rect->width = INT16_MAX;
|
||||||
if(rect->height >= INT16_MAX) rect->height = INT16_MAX;
|
if(rect->height >= INT16_MAX) rect->height = INT16_MAX;
|
||||||
|
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height);
|
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height);
|
||||||
c = cairo_create(cs);
|
c = cairo_create(cs);
|
||||||
|
|
||||||
|
|
@ -1229,8 +1182,8 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||||
|
|
||||||
cairo_paint(c);
|
cairo_paint(c);
|
||||||
|
|
||||||
cairo_set_source_surface(selected_cairo, cs, rect->x, rect->y);
|
cairo_set_source_surface(handle->wayland.front_cairo, cs, rect->x, rect->y);
|
||||||
cairo_paint(selected_cairo);
|
cairo_paint(handle->wayland.front_cairo);
|
||||||
|
|
||||||
cairo_destroy(c);
|
cairo_destroy(c);
|
||||||
cairo_surface_destroy(cs);
|
cairo_surface_destroy(cs);
|
||||||
|
|
@ -1239,7 +1192,6 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||||
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||||
}
|
}
|
||||||
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||||
if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) {
|
if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) {
|
||||||
struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context;
|
struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context;
|
||||||
|
|
@ -1282,7 +1234,6 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLForceRenderImpl(MwLL handle) {
|
static void MwLLForceRenderImpl(MwLL handle) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||||
|
|
||||||
handle->wayland.force_render = MwTRUE;
|
handle->wayland.force_render = MwTRUE;
|
||||||
|
|
@ -1294,8 +1245,6 @@ static void MwLLForceRenderImpl(MwLL handle) {
|
||||||
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
||||||
int x, y, xs, ys;
|
int x, y, xs, ys;
|
||||||
|
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
if(handle->wayland.cursor.setup) {
|
if(handle->wayland.cursor.setup) {
|
||||||
MwLLWaylandBufferDestroy(&handle->wayland.cursor);
|
MwLLWaylandBufferDestroy(&handle->wayland.cursor);
|
||||||
wl_surface_destroy(handle->wayland.cursor.surface);
|
wl_surface_destroy(handle->wayland.cursor.surface);
|
||||||
|
|
@ -1346,7 +1295,6 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
||||||
static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
|
static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
|
||||||
MwLL p = handle->wayland.parent;
|
MwLL p = handle->wayland.parent;
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
while(p != NULL) {
|
while(p != NULL) {
|
||||||
x += p->wayland.x;
|
x += p->wayland.x;
|
||||||
y += p->wayland.y;
|
y += p->wayland.y;
|
||||||
|
|
@ -1363,7 +1311,6 @@ static void MwLLShowImpl(MwLL handle, int show) {
|
||||||
if(!handle->wayland.configured) {
|
if(!handle->wayland.configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
/* Some guy on a mailing list said that "abusing" wl_surface_attach for this purpose is bad? This is documented behavior so please I beg of you let me know if there's a compositor that actually has a problem with this. */
|
/* Some guy on a mailing list said that "abusing" wl_surface_attach for this purpose is bad? This is documented behavior so please I beg of you let me know if there's a compositor that actually has a problem with this. */
|
||||||
if(handle->wayland.framebuffer.surface) {
|
if(handle->wayland.framebuffer.surface) {
|
||||||
wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0);
|
wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0);
|
||||||
|
|
@ -1382,16 +1329,16 @@ static void MwLLMakePopupImpl(MwLL handle, MwLL parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {
|
static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||||
xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny);
|
if(handle->wayland.has_decorations) {
|
||||||
xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy);
|
xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny);
|
||||||
|
xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
|
static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
|
||||||
(void)toggle;
|
(void)toggle;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||||
if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) {
|
if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) {
|
||||||
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context;
|
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context;
|
||||||
|
|
@ -1412,7 +1359,6 @@ static void MwLLFocusImpl(MwLL handle) {
|
||||||
|
|
||||||
static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
|
static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
|
||||||
MwLL topmost_parent = handle;
|
MwLL topmost_parent = handle;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||||
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
|
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
|
||||||
if(toggle) {
|
if(toggle) {
|
||||||
|
|
@ -1439,7 +1385,6 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
|
||||||
|
|
||||||
static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) {
|
static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) {
|
||||||
int i;
|
int i;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
if(handle->wayland.clipboard_buffer != NULL) {
|
if(handle->wayland.clipboard_buffer != NULL) {
|
||||||
free(handle->wayland.clipboard_buffer);
|
free(handle->wayland.clipboard_buffer);
|
||||||
|
|
@ -1466,7 +1411,6 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
|
||||||
|
|
||||||
static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
|
static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
|
||||||
int i;
|
int i;
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
if(clipboard_type == MwCLIPBOARD_PRIMARY) {
|
if(clipboard_type == MwCLIPBOARD_PRIMARY) {
|
||||||
if(handle->wayland.supports_zwp) {
|
if(handle->wayland.supports_zwp) {
|
||||||
for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) {
|
for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) {
|
||||||
|
|
@ -1486,7 +1430,6 @@ static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLMakeToolWindowImpl(MwLL handle) {
|
static void MwLLMakeToolWindowImpl(MwLL handle) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
handle->wayland.type_to_be = MwLL_WAYLAND_POPUP;
|
handle->wayland.type_to_be = MwLL_WAYLAND_POPUP;
|
||||||
}
|
}
|
||||||
|
|
@ -1494,14 +1437,12 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
|
||||||
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
||||||
MwLL topmost_parent = handle;
|
MwLL topmost_parent = handle;
|
||||||
|
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||||
|
|
||||||
*point = topmost_parent->wayland.cur_mouse_pos;
|
*point = topmost_parent->wayland.cur_mouse_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
rect->x = 0;
|
rect->x = 0;
|
||||||
rect->y = 0;
|
rect->y = 0;
|
||||||
|
|
@ -1515,7 +1456,6 @@ static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLEndStateChangeImpl(MwLL handle) {
|
static void MwLLEndStateChangeImpl(MwLL handle) {
|
||||||
WIDGET_CHECK(handle);
|
|
||||||
|
|
||||||
if(handle->wayland.detatching) {
|
if(handle->wayland.detatching) {
|
||||||
MwLL topmost_parent = handle->wayland.parent;
|
MwLL topmost_parent = handle->wayland.parent;
|
||||||
|
|
@ -1588,8 +1528,7 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
|
||||||
|
|
||||||
static void MwLLRaiseImpl(MwLL handle) {
|
static void MwLLRaiseImpl(MwLL handle) {
|
||||||
(void)handle;
|
(void)handle;
|
||||||
/* WIDGET_CHECK(handle);
|
/*
|
||||||
|
|
||||||
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
||||||
MwLL topmost_parent = handle;
|
MwLL topmost_parent = handle;
|
||||||
int children_num;
|
int children_num;
|
||||||
|
|
|
||||||
12
src/core.c
12
src/core.c
|
|
@ -18,7 +18,7 @@
|
||||||
MwLLEndDraw(handle->lowlevel); \
|
MwLLEndDraw(handle->lowlevel); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early);
|
static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early);
|
||||||
static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop);
|
static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop);
|
||||||
|
|
||||||
static void lldrawhandler(MwLL handle, void* data) {
|
static void lldrawhandler(MwLL handle, void* data) {
|
||||||
|
|
@ -354,6 +354,7 @@ void MwFreeWidget(MwWidget handle) {
|
||||||
|
|
||||||
for(i = 0; i < arrlen(handle->children); i++) {
|
for(i = 0; i < arrlen(handle->children); i++) {
|
||||||
MwFreeWidget(handle->children[i]);
|
MwFreeWidget(handle->children[i]);
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
arrfree(handle->children);
|
arrfree(handle->children);
|
||||||
|
|
||||||
|
|
@ -392,6 +393,15 @@ void MwFreeWidget(MwWidget handle) {
|
||||||
if(handle->root_monofont != NULL) MwFontFree(handle->root_monofont);
|
if(handle->root_monofont != NULL) MwFontFree(handle->root_monofont);
|
||||||
if(handle->root_boldmonofont != NULL) MwFontFree(handle->root_boldmonofont);
|
if(handle->root_boldmonofont != NULL) MwFontFree(handle->root_boldmonofont);
|
||||||
|
|
||||||
|
if(handle->parent) {
|
||||||
|
for(i = 0; i < arrlen(handle->parent->children); i++) {
|
||||||
|
if(handle->parent->children[i] == handle) {
|
||||||
|
arrdel(handle->parent->children, i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(handle);
|
free(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue