Compare commits
38 commits
630d8d6865
...
4e2c270908
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e2c270908 | |||
| cdf7657b19 | |||
| 7d2b5a17a4 | |||
| 9bdd80b421 | |||
| dfa8c22f1a | |||
| 21911dd899 | |||
| e7dc38175f | |||
| 7f361b9d15 | |||
| ec45c8828d | |||
| 83eb8c8dc4 | |||
| c5330cc184 | |||
| 12b89aab9b | |||
| e967523063 | |||
| aef5fe03a9 | |||
| a0da41210a | |||
| fb9919de2a | |||
| a18ca58f18 | |||
| f89eaf6901 | |||
| 2f3b8f2417 | |||
| 5872c43539 | |||
| 2a19c5e5cf | |||
| 87cbb582f7 | |||
| 47c9f8df4e | |||
| bc326491b5 | |||
| 960db8d3e3 | |||
| c2f8fb3f82 | |||
| e43a5291f5 | |||
| 58027c095f | |||
| cb5efd9224 | |||
| 954a4a8e15 | |||
| 9420878b93 | |||
| e8d692f05a | |||
| 4cb88fdc05 | |||
| b1a2d4d549 | |||
| f8c678ac53 | |||
| 2858679cc4 | |||
| 39dd112f2b | |||
| 2b15e7e0a3 |
18 changed files with 370 additions and 138 deletions
|
|
@ -479,7 +479,7 @@ if(MW_BUILD_VULKAN)
|
|||
)
|
||||
endif()
|
||||
|
||||
check_include_files(vulkan/VULKAN.h HAS_VK_HEADER)
|
||||
check_include_files(vulkan/vulkan.h HAS_VK_HEADER)
|
||||
if(HAS_VK_HEADER)
|
||||
target_compile_definitions(
|
||||
Mw
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ static void MWAPI tick(MwWidget handle, void* user_data, void* call_data) {
|
|||
MwGetClipboard(handle, MwCLIPBOARD_MAIN);
|
||||
cur_text = text2;
|
||||
MwGetClipboard(handle, MwCLIPBOARD_PRIMARY);
|
||||
MwForceRender(window);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ int main() {
|
|||
NULL);
|
||||
text_listbox = MwVaCreateWidget(MwListBoxClass, "label", box, 25, 150, 750, 700,
|
||||
MwNtext, "",
|
||||
MwNacceptsDnD, 1,
|
||||
NULL);
|
||||
|
||||
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@ static void MWAPI resize_window(MwWidget handle, void* user, void* call) {
|
|||
}
|
||||
|
||||
static void MWAPI layout_document(MwWidget handle, void* user, void* call) {
|
||||
int height = *(int*)call;
|
||||
MwRect size = *(MwRect*)call;
|
||||
|
||||
MwViewportSetSize(viewport, MwGetInteger(document, MwNwidth), height);
|
||||
MwViewportSetSize(viewport, size.width, size.height);
|
||||
MwVaApply(document,
|
||||
MwNheight, height,
|
||||
MwNwidth, size.width,
|
||||
MwNheight, size.height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -390,6 +390,13 @@ MWDECL void MWAPI MwFreeWidget(MwWidget handle);
|
|||
*/
|
||||
MWDECL void MWAPI MwGetFrame(MwWidget handle, MwRect* rect);
|
||||
|
||||
/*!
|
||||
* @brief Gets the clipping frame of the widget
|
||||
* @param handle Widget
|
||||
* @param rect Frame
|
||||
*/
|
||||
MWDECL void MWAPI MwGetClipFrame(MwWidget handle, MwRect* rect);
|
||||
|
||||
#ifdef _MILSKO
|
||||
MWDECL void MwForceRender_Internal(MwWidget handle);
|
||||
MWDECL void MwForceRender2_Internal(MwWidget handle, void* ptr);
|
||||
|
|
|
|||
|
|
@ -220,6 +220,13 @@ MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color,
|
|||
*/
|
||||
MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled);
|
||||
|
||||
/*!
|
||||
* @brief Calculate intersect of 2 rectangles
|
||||
* @param a 1st rectangle
|
||||
* @param a 2nd rectangle
|
||||
*/
|
||||
MWDECL void MwIntersectRect(MwRect* a, const MwRect* b);
|
||||
|
||||
/* text.c */
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -257,6 +257,14 @@ struct _MwLLWaylandLayerSurface {
|
|||
struct zwlr_layer_surface_v1* surface;
|
||||
};
|
||||
|
||||
struct _MwLLWaylandSubsurface {
|
||||
MwLL parent;
|
||||
|
||||
struct xdg_surface* xdg_surface;
|
||||
struct wl_subsurface* subsurface;
|
||||
struct wl_subcompositor* subcompositor;
|
||||
};
|
||||
|
||||
/* Shared set of anything needed for a shm buffer. */
|
||||
struct _MwLLWaylandShmBuffer {
|
||||
struct wl_shm* shm;
|
||||
|
|
@ -271,6 +279,7 @@ struct _MwLLWaylandShmBuffer {
|
|||
MwU8* buf;
|
||||
MwU8* buf_back;
|
||||
MwU64 buf_size;
|
||||
MwU64 buf_capacity;
|
||||
int fd;
|
||||
int fd_back;
|
||||
MwBool setup;
|
||||
|
|
@ -282,6 +291,7 @@ enum _MwLLWaylandType {
|
|||
MwLL_WAYLAND_SUBLEVEL,
|
||||
MwLL_WAYLAND_POPUP,
|
||||
MwLL_WAYLAND_LAYER_SURFACE,
|
||||
MwLL_WAYLAND_SUBSURFACE,
|
||||
};
|
||||
|
||||
typedef struct wl_clipboard_device_context {
|
||||
|
|
@ -314,6 +324,8 @@ struct _MwLLWayland {
|
|||
struct _MwLLWaylandPopup* popup;
|
||||
/* Pointer for data that's only loaded if the widget is a layer surface */
|
||||
struct _MwLLWaylandLayerSurface* layer_surface;
|
||||
/* Pointer for data that's only loaded if the widget is a subsurface */
|
||||
struct _MwLLWaylandSubsurface* subsurface;
|
||||
};
|
||||
|
||||
enum _MwLLWaylandType type;
|
||||
|
|
@ -427,6 +439,8 @@ struct _MwLLWayland {
|
|||
MwBool do_cascading_draw;
|
||||
int cascading_child_num;
|
||||
|
||||
cairo_surface_t* snapshot;
|
||||
|
||||
MwBool dispatching_resize;
|
||||
|
||||
struct _MwLLWaylandShmBuffer framebuffer;
|
||||
|
|
@ -466,6 +480,12 @@ void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* handle);
|
|||
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height);
|
||||
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer);
|
||||
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer);
|
||||
/* Resize an already set-up shm buffer pair in place, growing the backing pool with
|
||||
* wl_shm_pool_resize instead of tearing it down and recreating it from scratch. */
|
||||
void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height);
|
||||
|
||||
void MwLLWaylandFramebufferResize(struct _MwLLWayland* wayland);
|
||||
void MwLLWaylandBackbufferResize(struct _MwLLWayland* wayland);
|
||||
|
||||
void MwLLWaylandRegionSetup(MwLL handle);
|
||||
void MwLLWaylandRegionInvalidate(MwLL handle);
|
||||
|
|
@ -488,12 +508,6 @@ void MwLLWaylandFlush(MwLL handle);
|
|||
/* recursively dispatch the key event to focused widgets. */
|
||||
void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down);
|
||||
|
||||
/* Standard procedure before event callbacks in Wayland */
|
||||
#define WAYLAND_EVENT_OP_START(self)
|
||||
|
||||
/* Footer for WAYLAND_EVENT_OP_START */
|
||||
#define WAYLAND_EVENT_OP_END(self)
|
||||
|
||||
/* the two decoration manager constructs */
|
||||
typedef struct zxdg_decoration_manager_v1_context {
|
||||
struct zxdg_decoration_manager_v1* manager;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
#define MwNminute "Iminute"
|
||||
#define MwNsecond "Isecond"
|
||||
#define MwNtype "Itype"
|
||||
#define MwNstrikethrough "Istrikethrough"
|
||||
#define MwNunderline "Iunderline"
|
||||
|
||||
#define MwNtitle "Stitle"
|
||||
#define MwNtext "Stext"
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@
|
|||
<string />
|
||||
</handler>
|
||||
<handler name="layout">
|
||||
<integer pointer="yes" />
|
||||
<struct defname="MwRect" pointer="yes" />
|
||||
</handler>
|
||||
</handlers>
|
||||
<enumerations>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
|||
|
||||
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
|
||||
|
||||
memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size);
|
||||
memset(wayland->framebuffer.buf_back, 255, wayland->framebuffer.buf_size);
|
||||
if(wayland->configured)
|
||||
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
|
||||
if(wayland->framebuffer.fifo)
|
||||
|
|
@ -38,7 +38,7 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
|
|||
|
||||
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
|
||||
|
||||
memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size);
|
||||
memset(wayland->backbuffer.buf_back, 0, wayland->backbuffer.buf_size);
|
||||
if(wayland->configured)
|
||||
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
|
||||
// if(wayland->framebuffer.fifo)
|
||||
|
|
@ -90,6 +90,8 @@ void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, M
|
|||
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
||||
buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0);
|
||||
|
||||
buffer->buf_capacity = buffer->buf_size;
|
||||
|
||||
fsync(buffer->fd);
|
||||
fsync(buffer->fd_back);
|
||||
|
||||
|
|
@ -108,8 +110,8 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
|||
if(!buffer->setup) {
|
||||
return;
|
||||
}
|
||||
if(buffer->buf) munmap(buffer->buf, buffer->buf_size);
|
||||
if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_size);
|
||||
if(buffer->buf) munmap(buffer->buf, buffer->buf_capacity);
|
||||
if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_capacity);
|
||||
if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer);
|
||||
if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back);
|
||||
if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool);
|
||||
|
|
@ -119,11 +121,61 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
|||
buffer->setup = MwFALSE;
|
||||
}
|
||||
|
||||
void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
|
||||
MwLLWaylandBufferDestroy(buffer);
|
||||
MwLLWaylandBufferSetup(buffer, width, height);
|
||||
memset(buffer->buf_back, 0, buffer->buf_size);
|
||||
memset(buffer->buf, 0, buffer->buf_size);
|
||||
}
|
||||
|
||||
void MwLLWaylandFramebufferResize(struct _MwLLWayland* wayland) {
|
||||
MwLLWaylandBufferResize(&wayland->framebuffer, wayland->ww, wayland->wh);
|
||||
|
||||
MwLLCairoFrontDestroy(&wayland->cairo);
|
||||
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
|
||||
|
||||
if(wayland->configured)
|
||||
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
|
||||
if(wayland->framebuffer.fifo)
|
||||
wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
|
||||
|
||||
wl_surface_commit(wayland->framebuffer.surface);
|
||||
|
||||
MwLLWaylandHangUntilConfigured((MwLL)wayland);
|
||||
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer);
|
||||
}
|
||||
|
||||
void MwLLWaylandBackbufferResize(struct _MwLLWayland* wayland) {
|
||||
MwU32 w = wayland->ww;
|
||||
MwU32 h = wayland->wh;
|
||||
|
||||
if(wayland->type != MwLL_WAYLAND_TOPLEVEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!wayland->has_decorations && wayland->do_csd) {
|
||||
w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT);
|
||||
h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM);
|
||||
}
|
||||
|
||||
MwLLWaylandBufferResize(&wayland->backbuffer, w, h);
|
||||
|
||||
MwLLCairoBackDestroy(&wayland->cairo);
|
||||
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
|
||||
|
||||
if(wayland->configured)
|
||||
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
|
||||
wl_surface_commit(wayland->backbuffer.surface);
|
||||
MwLLWaylandHangUntilConfigured((MwLL)wayland);
|
||||
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer);
|
||||
}
|
||||
|
||||
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
|
||||
if(self->wayland.configured) {
|
||||
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
|
||||
if(buffer->surface) {
|
||||
// Yes this is needed every time, it's how we fix weston.
|
||||
// it's also how we fix comboboxes.
|
||||
if(self->wayland.configured) {
|
||||
wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
|
||||
static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos);
|
||||
static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos);
|
||||
|
||||
/* Recursively dispatch a key event to a widget and its children */
|
||||
static void recursive_dispatch_key(MwLL handle, int* k) {
|
||||
|
|
@ -72,8 +72,6 @@ static void new_protocol(void* data, struct wl_registry* registry,
|
|||
(void)version;
|
||||
(void)registry;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface);
|
||||
if(cb != NULL) {
|
||||
shput(self->wayland.wl_protocol_map, interface, cb->setup(name, data, version));
|
||||
|
|
@ -83,8 +81,6 @@ static void new_protocol(void* data, struct wl_registry* registry,
|
|||
} else {
|
||||
// printf("unknown interface %s\n", interface);
|
||||
}
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
/* `wl_registry.global_remove` callback */
|
||||
|
|
@ -154,11 +150,7 @@ static void wl_data_device_enter(void* data,
|
|||
(void)y;
|
||||
(void)id;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
self->ll->wayland.clipboard_serial = serial;
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
static void wl_data_device_leave(void* data,
|
||||
struct wl_data_device* wl_data_device) {
|
||||
|
|
@ -398,7 +390,6 @@ static void wl_data_source_listener_target(void* data,
|
|||
(void)data;
|
||||
(void)wl_data_source;
|
||||
(void)mime_type;
|
||||
printf("test\n");
|
||||
};
|
||||
static void wl_data_source_listener_send(void* data,
|
||||
struct wl_data_source* wl_data_source,
|
||||
|
|
@ -408,12 +399,10 @@ static void wl_data_source_listener_send(void* data,
|
|||
(void)wl_data_source;
|
||||
(void)mime_type;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
if(self->wayland.clipboard_buffer != NULL) {
|
||||
write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer));
|
||||
close(fd);
|
||||
}
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
static void wl_data_source_listener_cancelled(void* data,
|
||||
struct wl_data_source* wl_data_source);
|
||||
|
|
@ -428,8 +417,6 @@ static void wl_data_source_listener_cancelled(void* data,
|
|||
struct wl_data_source* wl_data_source) {
|
||||
MwLL self = data;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
if(wl_data_source)
|
||||
wl_data_source_destroy(wl_data_source);
|
||||
|
||||
|
|
@ -443,8 +430,6 @@ static void wl_data_source_listener_cancelled(void* data,
|
|||
wl_data_source_offer(self->wayland.clipboard_source.wl, "text/uri-list");
|
||||
|
||||
wl_data_source_add_listener(self->wayland.clipboard_source.wl, &wl_data_source_listener, self);
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
static void zwp_primary_selection_source_v1_send(void* data,
|
||||
|
|
@ -455,22 +440,16 @@ static void zwp_primary_selection_source_v1_send(void* data,
|
|||
(void)wl_data_source;
|
||||
(void)mime_type;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
if(self->wayland.clipboard_buffer != NULL) {
|
||||
write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer));
|
||||
close(fd);
|
||||
}
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
static void zwp_primary_selection_source_v1_cancelled(void* data,
|
||||
struct zwp_primary_selection_source_v1* wl_data_source) {
|
||||
MwLL self = data;
|
||||
(void)wl_data_source;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
zwp_primary_selection_source_v1_destroy(self->wayland.clipboard_source.zwp);
|
||||
|
||||
self->wayland.clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(self->wayland.clipboard_manager.zwp);
|
||||
|
|
@ -480,8 +459,6 @@ static void zwp_primary_selection_source_v1_cancelled(void* data,
|
|||
zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "TEXT");
|
||||
zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "STRING");
|
||||
zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "UTF8_STRING");
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
struct zwp_primary_selection_source_v1_listener zwp_primary_selection_source_v1_listener = {
|
||||
|
|
@ -578,7 +555,6 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria
|
|||
(void)surface_y;
|
||||
(void)wl_pointer;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
|
||||
if(self->wayland.framebuffer.surface == surface) {
|
||||
|
|
@ -591,19 +567,18 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria
|
|||
if(self->wayland.backbuffer.surface == surface) {
|
||||
curSurface = surface;
|
||||
}
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
|
||||
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
|
||||
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
|
||||
};
|
||||
|
||||
/* `wl_pointer.leave` callback */
|
||||
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
|
||||
struct wl_surface* surface) {
|
||||
MwLL self = data;
|
||||
(void)data;
|
||||
(void)wl_pointer;
|
||||
(void)serial;
|
||||
(void)surface;
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
curSurface = NULL;
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
static void xdg_borderless_step_mdown(MwLL self, MwMouse p, MwU32 serial) {
|
||||
|
|
@ -673,15 +648,11 @@ static void relative_pointer_motion(void* data,
|
|||
(void)dx;
|
||||
(void)dy;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
p.point.x = wl_fixed_to_int(dxUnaccel);
|
||||
p.point.y = wl_fixed_to_int(dyUnaccel);
|
||||
|
||||
recursive_dispatch_move(self, &p);
|
||||
if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
}
|
||||
|
||||
struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener =
|
||||
|
|
@ -713,7 +684,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|||
(void)time;
|
||||
(void)wl_pointer;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
|
||||
currentlyHeldWidgets = topmost_parent->wayland.currentlyHeldWidgets;
|
||||
|
|
@ -722,9 +692,9 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
||||
}
|
||||
|
||||
// if(self->wayland.backbuffer.surface) {
|
||||
// inArea |= self->wayland.backbuffer.surface == curSurface;
|
||||
// }
|
||||
if(self->wayland.backbuffer.surface) {
|
||||
inArea |= self->wayland.backbuffer.surface == curSurface;
|
||||
}
|
||||
|
||||
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
|
||||
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
|
||||
|
|
@ -749,8 +719,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|||
if(self->wayland.backbuffer.surface) {
|
||||
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
|
||||
}
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) {
|
||||
|
|
@ -780,7 +748,7 @@ static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
|
|||
}
|
||||
};
|
||||
|
||||
static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos) {
|
||||
static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos) {
|
||||
MwLL topmost_parent = child;
|
||||
MwPoint point;
|
||||
MwPoint relative_mouse_pos;
|
||||
|
|
@ -791,8 +759,13 @@ static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoi
|
|||
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;
|
||||
/* if the topmost parent is a popup/subwindow then its x/y is irrelevant to us. */
|
||||
if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP && topmost_parent->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
||||
if(topmost_parent->wayland.x > 0)
|
||||
absolute_pos.x += topmost_parent->wayland.x;
|
||||
if(topmost_parent->wayland.y > 0)
|
||||
absolute_pos.y += topmost_parent->wayland.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -871,8 +844,6 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
|
|||
(void)serial;
|
||||
(void)time;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
if(self->wayland.type != MwLL_WAYLAND_POPUP) {
|
||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
}
|
||||
|
|
@ -883,23 +854,24 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
|
|||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
||||
}
|
||||
|
||||
if(inArea) {
|
||||
switch(button) {
|
||||
case BTN_LEFT:
|
||||
p.button = MwMOUSE_LEFT;
|
||||
break;
|
||||
case BTN_MIDDLE:
|
||||
p.button = MwMOUSE_MIDDLE;
|
||||
break;
|
||||
case BTN_RIGHT:
|
||||
p.button = MwMOUSE_RIGHT;
|
||||
break;
|
||||
}
|
||||
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
|
||||
switch(button) {
|
||||
case BTN_LEFT:
|
||||
p.button = MwMOUSE_LEFT;
|
||||
break;
|
||||
case BTN_MIDDLE:
|
||||
p.button = MwMOUSE_MIDDLE;
|
||||
break;
|
||||
case BTN_RIGHT:
|
||||
p.button = MwMOUSE_RIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
if(inArea) {
|
||||
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
|
||||
arrsetlen(self->wayland.currentlyHeldWidgets, 0);
|
||||
mouse_dispatch(self, p, state);
|
||||
}
|
||||
|
||||
if(self->wayland.backbuffer.surface) {
|
||||
if(!self->wayland.has_decorations && self->wayland.do_csd) {
|
||||
if(state != WL_POINTER_BUTTON_STATE_RELEASED)
|
||||
|
|
@ -910,8 +882,6 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
|
|||
}
|
||||
|
||||
MwLLForceRender(self);
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
/* `wl_pointer.axis` callback */
|
||||
|
|
@ -974,13 +944,9 @@ static void keyboard_enter(void* data,
|
|||
(void)surface;
|
||||
(void)keys;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
self->wayland.keyboard_serial = serial;
|
||||
|
||||
MwLLDispatch(self, focus_in, NULL);
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
/* `wl_keyboard.leave` callback */
|
||||
|
|
@ -993,11 +959,7 @@ static void keyboard_leave(void* data,
|
|||
(void)serial;
|
||||
(void)surface;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
MwLLDispatch(self, focus_out, NULL);
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down) {
|
||||
|
|
@ -1043,8 +1005,6 @@ static void keyboard_key(void* data,
|
|||
|
||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
if(self->wayland.framebuffer.surface) {
|
||||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
||||
}
|
||||
|
|
@ -1062,7 +1022,7 @@ static void keyboard_key(void* data,
|
|||
int i;
|
||||
|
||||
if(!self->wayland.xkb_keymap) {
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1077,7 +1037,7 @@ static void keyboard_key(void* data,
|
|||
}
|
||||
syms_num = xkb_keymap_key_get_syms_by_level(self->wayland.xkb_keymap, keycode, layout, level, &syms_out);
|
||||
if(syms_out == NULL) {
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1151,8 +1111,6 @@ static void keyboard_key(void* data,
|
|||
if(!MwWaylandVulkan) {
|
||||
MwLLDispatch(self, draw, NULL);
|
||||
}
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
/* `wl_keyboard.modifiers` callback */
|
||||
|
|
@ -1169,13 +1127,9 @@ static void keyboard_modifiers(void* data,
|
|||
(void)group;
|
||||
(void)mods_latched;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
self->wayland.mod_state = 0;
|
||||
self->wayland.mod_state |= mods_depressed;
|
||||
self->wayland.mod_state |= mods_locked;
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat) {
|
||||
|
|
@ -1246,8 +1200,6 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
|||
MwU32 capabilities) {
|
||||
MwLL self = data;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
/* Always remember the seat itself, regardless of which capabilities it has - this is
|
||||
* both what setup_clipboard()/setup_zwp_clipboard() below use, and what lets
|
||||
* wl_seat_interface_destroy() release it later even on a keyboard-only seat. */
|
||||
|
|
@ -1261,7 +1213,6 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
|||
self->wayland.pointer = wl_seat_get_pointer(wl_seat);
|
||||
wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data);
|
||||
}
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
|
||||
/* Only hooked up if this seat actually has a pointer: wl_data_device.get_data_device()
|
||||
* requires a non-null seat, and pointer_seat is only ever null before the first
|
||||
|
|
@ -1399,6 +1350,8 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
|
|||
(void)version;
|
||||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
|
||||
} else if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
|
||||
wayland->subsurface->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -1409,6 +1362,9 @@ static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, way
|
|||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
wl_subcompositor_destroy(wayland->toplevel->scompositor);
|
||||
}
|
||||
if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
|
||||
wl_subcompositor_destroy(wayland->subsurface->subcompositor);
|
||||
}
|
||||
}
|
||||
|
||||
/* xdg_wm_base setup function */
|
||||
|
|
@ -1549,19 +1505,11 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
|
|||
WL_INTERFACE(zwp_relative_pointer_manager_v1);
|
||||
WL_INTERFACE(xdg_wm_base);
|
||||
WL_INTERFACE(zwlr_layer_shell_v1); /* Only used for layer surface, but we use it always if it's turned into a tool window */
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
WL_INTERFACE(zxdg_decoration_manager_v1);
|
||||
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
WL_INTERFACE(wl_seat);
|
||||
WL_INTERFACE(wp_fifo_manager_v1);
|
||||
} else if(wayland->type == MwLL_WAYLAND_POPUP) {
|
||||
WL_INTERFACE(wl_seat);
|
||||
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
WL_INTERFACE(wl_seat);
|
||||
} else {
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
}
|
||||
#undef WL_INTERFACE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,10 +173,7 @@ static void xdg_toplevel_configure(void* data,
|
|||
if(self->wayland.resizing == 0) {
|
||||
xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh);
|
||||
|
||||
MwLLWaylandBackbufferDestroy(&self->wayland);
|
||||
MwLLWaylandBackbufferSetup(&self->wayland);
|
||||
MwLLWaylandFramebufferDestroy(&self->wayland);
|
||||
MwLLWaylandFramebufferSetup(&self->wayland);
|
||||
MwLLWaylandFramebufferResize(&self->wayland);
|
||||
|
||||
MwLLWaylandRegionSetup(self);
|
||||
MwLLDispatch(self, resize, NULL);
|
||||
|
|
@ -196,9 +193,8 @@ static void xdg_toplevel_close(
|
|||
void* data, struct xdg_toplevel* xdg_toplevel) {
|
||||
MwLL self = data;
|
||||
(void)xdg_toplevel;
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
MwLLDispatch(self, close, NULL);
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
/* `xdg_surface.configure` callback */
|
||||
|
|
@ -370,6 +366,8 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|||
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface;
|
||||
} else if(parent->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
|
||||
r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface;
|
||||
} else if(parent->wayland.type == MwLL_WAYLAND_SUBSURFACE) {
|
||||
r->wayland.sublevel->xdg_surface = parent->wayland.subsurface->xdg_surface;
|
||||
} else if(parent->wayland.type == MwLL_WAYLAND_POPUP) {
|
||||
r->wayland.sublevel->xdg_surface = parent->wayland.popup->xdg_surface;
|
||||
}
|
||||
|
|
@ -400,6 +398,66 @@ static void destroy_sublevel(MwLL r) {
|
|||
r->wayland.configured = MwFALSE;
|
||||
}
|
||||
|
||||
/* Subsurface setup function */
|
||||
static void setup_subsurface(MwLL parent, MwLL r, int x, int y) {
|
||||
struct wl_compositor* compositor = parent->wayland.compositor;
|
||||
struct wl_surface* parent_surface = parent->wayland.framebuffer.surface;
|
||||
|
||||
r->wayland.subsurface = malloc(sizeof(struct _MwLLWaylandSubsurface));
|
||||
r->wayland.subsurface->parent = parent;
|
||||
|
||||
r->wayland.type = MwLL_WAYLAND_SUBSURFACE;
|
||||
|
||||
r->wayland.display = parent->wayland.display;
|
||||
|
||||
MwLLWaylandSetupCallbacks(&r->wayland);
|
||||
|
||||
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
|
||||
r->wayland.display = parent->wayland.display;
|
||||
|
||||
if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
r->wayland.subsurface->xdg_surface = parent->wayland.toplevel->xdg_surface;
|
||||
} else {
|
||||
r->wayland.subsurface->xdg_surface = parent->wayland.subsurface->xdg_surface;
|
||||
}
|
||||
|
||||
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
|
||||
if(wl_display_roundtrip(r->wayland.display) == -1) {
|
||||
printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display));
|
||||
raise(SIGTRAP);
|
||||
return;
|
||||
}
|
||||
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
|
||||
|
||||
r->wayland.subsurface->subsurface = wl_subcompositor_get_subsurface(r->wayland.subsurface->subcompositor, r->wayland.framebuffer.surface, parent_surface);
|
||||
|
||||
wl_subsurface_set_desync(r->wayland.subsurface->subsurface);
|
||||
wl_subsurface_set_position(r->wayland.subsurface->subsurface, x, y);
|
||||
|
||||
if(parent) {
|
||||
wl_subsurface_place_above(r->wayland.subsurface->subsurface, parent->wayland.framebuffer.surface);
|
||||
}
|
||||
|
||||
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
|
||||
r->wayland.xkb_state = parent->wayland.xkb_state;
|
||||
|
||||
r->wayland.configured = MwTRUE;
|
||||
|
||||
MwLLWaylandFramebufferSetup(&r->wayland);
|
||||
MwLLWaylandBackbufferSetup(&r->wayland);
|
||||
}
|
||||
|
||||
/* Subsurface setup function */
|
||||
static void destroy_subsurface(MwLL r) {
|
||||
MwLLWaylandBackbufferDestroy(&r->wayland);
|
||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||
|
||||
free(r->wayland.sublevel);
|
||||
|
||||
r->wayland.configured = MwFALSE;
|
||||
}
|
||||
|
||||
static void popup_configure(void* data,
|
||||
struct xdg_popup* xdg_popup,
|
||||
int32_t x,
|
||||
|
|
@ -834,6 +892,7 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
|||
r->wayland.parent = parent;
|
||||
r->wayland.valid = MwTRUE;
|
||||
|
||||
printf("type %d\n", ty);
|
||||
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
||||
if(parent == NULL) {
|
||||
setup_toplevel(r, x, y);
|
||||
|
|
@ -866,6 +925,9 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
|||
case MwLL_WAYLAND_LAYER_SURFACE:
|
||||
setup_layer_surface(r, x, y, width, height);
|
||||
break;
|
||||
case MwLL_WAYLAND_SUBSURFACE:
|
||||
setup_subsurface(parent, r, x, y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -943,6 +1005,13 @@ static void draw_children(MwLL handle) {
|
|||
|
||||
cairo_reset_clip(handle->wayland.cairo.front_cairo_back);
|
||||
|
||||
if(handle->wayland.snapshot) {
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, handle->wayland.snapshot, 0, 0);
|
||||
cairo_paint(handle->wayland.cairo.front_cairo_back);
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
|
||||
}
|
||||
|
||||
MwLLWaylandChildrenIterate(handle, draw_child);
|
||||
|
||||
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||
|
|
@ -986,6 +1055,9 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
int i;
|
||||
struct timeval tv;
|
||||
int select_ret;
|
||||
MwLL topmost_parent = handle;
|
||||
|
||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
|
||||
event_loop(handle);
|
||||
// wl_display_cancel_read(handle->wayland.display);
|
||||
|
|
@ -1025,6 +1097,12 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
printf("widget invalid\n");
|
||||
}
|
||||
|
||||
for(i = 0; i < arrlen(topmost_parent->wayland.currentlyHeldWidgets); i++) {
|
||||
if(topmost_parent->wayland.currentlyHeldWidgets[i] == handle) {
|
||||
arrdel(topmost_parent->wayland.currentlyHeldWidgets, i);
|
||||
}
|
||||
}
|
||||
|
||||
// pthread_mutex_destroy(&handle->wayland.eventsMutex);
|
||||
|
||||
free(handle);
|
||||
|
|
@ -1074,6 +1152,9 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
|||
break;
|
||||
case MwLL_WAYLAND_UNKNOWN:
|
||||
break;
|
||||
case MwLL_WAYLAND_SUBSURFACE:
|
||||
wl_subsurface_set_position(handle->wayland.subsurface->subsurface, x, y);
|
||||
break;
|
||||
}
|
||||
MwLLWaylandRegionSetup(handle);
|
||||
|
||||
|
|
@ -1104,10 +1185,7 @@ static void actually_set_wh(MwLL handle) {
|
|||
MwLLWaylandRegionSetup(handle);
|
||||
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) recursive_render(handle);
|
||||
|
||||
MwLLWaylandFramebufferDestroy(&handle->wayland);
|
||||
MwLLWaylandFramebufferSetup(&handle->wayland);
|
||||
MwLLWaylandBackbufferDestroy(&handle->wayland);
|
||||
MwLLWaylandBackbufferSetup(&handle->wayland);
|
||||
MwLLWaylandFramebufferResize(&handle->wayland);
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1297,6 +1375,21 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
|||
}
|
||||
root->wayland.do_cascading_draw = MwTRUE;
|
||||
|
||||
if(handle->wayland.snapshot) {
|
||||
cairo_surface_destroy(handle->wayland.snapshot);
|
||||
handle->wayland.snapshot = NULL;
|
||||
}
|
||||
if(handle->wayland.ww > 0 && handle->wayland.wh > 0) {
|
||||
cairo_t* snap_cr;
|
||||
|
||||
handle->wayland.snapshot = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh);
|
||||
snap_cr = cairo_create(handle->wayland.snapshot);
|
||||
cairo_set_operator(snap_cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface(snap_cr, handle->wayland.cairo.front_cs_back, 0, 0);
|
||||
cairo_paint(snap_cr);
|
||||
cairo_destroy(snap_cr);
|
||||
}
|
||||
|
||||
if(handle->wayland.configured) {
|
||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
||||
|
|
|
|||
|
|
@ -978,6 +978,7 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
};
|
||||
case SelectionNotify:
|
||||
{
|
||||
#if 0
|
||||
handle->x11.clipboard_pending = 0;
|
||||
|
||||
if(ev.xselection.property == handle->x11.xdnd_selection) {
|
||||
|
|
@ -1066,6 +1067,7 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
}
|
||||
XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection);
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
}
|
||||
if(render) {
|
||||
|
|
|
|||
53
src/core.c
53
src/core.c
|
|
@ -69,7 +69,8 @@ static void lldrawhandler(MwLL handle, void* data) {
|
|||
static void lluphandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
MwMouse* p = data;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
if(p->button == MwMOUSE_LEFT) h->pressed = 0;
|
||||
h->mouse_point.x = p->point.x;
|
||||
|
|
@ -83,7 +84,8 @@ static void lluphandler(MwLL handle, void* data) {
|
|||
static void lldownhandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
MwMouse* p = data;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
if(p->button == MwMOUSE_LEFT) h->pressed = 1;
|
||||
h->mouse_point.x = p->point.x;
|
||||
|
|
@ -158,7 +160,8 @@ static void llmovehandler(MwLL handle, void* data) {
|
|||
static void llkeyhandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
int key = *(int*)data;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
MwDispatch3(h, key, key);
|
||||
MwDispatchUserHandler(h, MwNkeyHandler, data);
|
||||
|
|
@ -166,28 +169,32 @@ static void llkeyhandler(MwLL handle, void* data) {
|
|||
|
||||
static void llkeyrelhandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
MwDispatchUserHandler(h, MwNkeyReleaseHandler, data);
|
||||
}
|
||||
|
||||
static void llfocusinhandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
MwDispatchUserHandler(h, MwNfocusInHandler, data);
|
||||
}
|
||||
|
||||
static void llfocusouthandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
MwDispatchUserHandler(h, MwNfocusOutHandler, data);
|
||||
}
|
||||
|
||||
static void llclipboardhandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
MwDispatch3(h, clipboard, data);
|
||||
MwDispatchUserHandler(h, MwNclipboardHandler, data);
|
||||
|
|
@ -195,7 +202,8 @@ static void llclipboardhandler(MwLL handle, void* data) {
|
|||
|
||||
static void lldraganddrophandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(MwGetInteger(h, MwNdisabled) == 1) return;
|
||||
int n;
|
||||
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
|
||||
|
||||
MwDispatchUserHandler(h, MwNdragAndDropHandler, data);
|
||||
}
|
||||
|
|
@ -671,7 +679,7 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
|
|||
if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n);
|
||||
}
|
||||
|
||||
if(strcmp(key, MwNacceptsDnD) == 0) {
|
||||
if(strcmp(key, MwNacceptsDnD) == 0 && n) {
|
||||
if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel);
|
||||
}
|
||||
}
|
||||
|
|
@ -1233,4 +1241,31 @@ void MwGetFrame(MwWidget handle, MwRect* rect) {
|
|||
rect->height = MwGetInteger(handle, MwNheight);
|
||||
}
|
||||
|
||||
void MwGetClipFrame(MwWidget handle, MwRect* rect) {
|
||||
MwWidget child = handle;
|
||||
MwWidget p = handle->parent;
|
||||
int o_x = 0, o_y = 0;
|
||||
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
rect->width = MwGetInteger(handle, MwNwidth);
|
||||
rect->height = MwGetInteger(handle, MwNheight);
|
||||
while(p != NULL && p->widget_class != MwWindowClass) {
|
||||
MwRect pclip;
|
||||
|
||||
o_x += MwGetInteger(child, MwNx);
|
||||
o_y += MwGetInteger(child, MwNy);
|
||||
|
||||
pclip.x = -o_x;
|
||||
pclip.y = -o_y;
|
||||
pclip.width = MwGetInteger(p, MwNwidth);
|
||||
pclip.height = MwGetInteger(p, MwNheight);
|
||||
MwIntersectRect(rect, &pclip);
|
||||
if(rect->width == 0 || rect->height == 0) break;
|
||||
|
||||
child = p;
|
||||
p = p->parent;
|
||||
}
|
||||
}
|
||||
|
||||
const char* MwVersionString = MwVERSION;
|
||||
|
|
|
|||
36
src/draw.c
36
src/draw.c
|
|
@ -39,7 +39,9 @@ static int hex(const char* txt, int len) {
|
|||
}
|
||||
|
||||
static void color_set_disabled_if_disabled(MwWidget handle, MwLLColor rgb) {
|
||||
if(MwGetInteger(handle, MwNdisabled) == 1) {
|
||||
int n;
|
||||
|
||||
if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) {
|
||||
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground));
|
||||
|
||||
if(c != NULL) {
|
||||
|
|
@ -1123,3 +1125,35 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
|
|||
|
||||
return px;
|
||||
}
|
||||
|
||||
static int _min(int a, int b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static int _max(int a, int b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
void MwIntersectRect(MwRect* a, const MwRect* b) {
|
||||
int x;
|
||||
int y;
|
||||
int right;
|
||||
int bottom;
|
||||
|
||||
x = _max(a->x, b->x);
|
||||
y = _max(a->y, b->y);
|
||||
right = _min(a->x + a->width, b->x + b->width);
|
||||
bottom = _min(a->y + a->height, b->y + b->height);
|
||||
|
||||
a->x = x;
|
||||
a->y = y;
|
||||
|
||||
if(right <= x || bottom <= x) {
|
||||
a->width = 0;
|
||||
a->height = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
a->width = right - x;
|
||||
a->height = bottom - y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,8 +82,9 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
|
|||
char* last = input;
|
||||
int cp;
|
||||
MwLLColor fadedColor = NULL;
|
||||
int n;
|
||||
|
||||
if(MwGetInteger(handle, MwNdisabled) == 1) {
|
||||
if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) {
|
||||
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground));
|
||||
|
||||
if(c != NULL) {
|
||||
|
|
@ -107,8 +108,10 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
|
|||
input += MwUTF8ToUTF32(input, &cp);
|
||||
|
||||
if(*input == 0 || cp == '\n') {
|
||||
char* line = malloc(input - last + 1);
|
||||
int i;
|
||||
char* line = malloc(input - last + 1);
|
||||
int i;
|
||||
MwPoint l[2];
|
||||
int tw, th;
|
||||
|
||||
if(!line) {
|
||||
printf("Out Of Memory\n");
|
||||
|
|
@ -134,20 +137,38 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
|
|||
continue;
|
||||
}
|
||||
|
||||
tw = MwTextWidth(handle, ttf, line);
|
||||
th = MwTextHeight(handle, ttf, line);
|
||||
|
||||
p.x = point->x;
|
||||
if(align == MwALIGNMENT_CENTER) {
|
||||
p.x -= MwTextWidth(handle, ttf, line) / 2;
|
||||
p.x -= tw / 2;
|
||||
} else if(align == MwALIGNMENT_END) {
|
||||
p.x -= MwTextWidth(handle, ttf, line);
|
||||
p.x -= tw;
|
||||
}
|
||||
|
||||
l[0].x = p.x;
|
||||
l[1].x = l[0].x + tw;
|
||||
|
||||
#ifdef TTF
|
||||
if(MwFLDrawText)
|
||||
if(is_bitmap(handle, ttf) || ttf == NULL || MwFLDrawText(handle, ttf, &p, line, fadedColor ? fadedColor : color))
|
||||
#endif
|
||||
bitmap_MwDrawText(handle, &p, line, is_bold(handle, ttf), fadedColor ? fadedColor : color);
|
||||
|
||||
p.y += MwTextHeight(handle, ttf, line);
|
||||
l[0].y = l[1].y = p.y;
|
||||
|
||||
if((n = MwGetInteger(handle, MwNstrikethrough)) != MwDEFAULT && n) {
|
||||
MwLLLine(handle->lowlevel, l, color);
|
||||
}
|
||||
|
||||
if((n = MwGetInteger(handle, MwNunderline)) != MwDEFAULT && n) {
|
||||
l[0].y += th / 2;
|
||||
l[1].y += th / 2;
|
||||
MwLLLine(handle->lowlevel, l, color);
|
||||
}
|
||||
|
||||
p.y += th;
|
||||
|
||||
free(line);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ static void draw(MwWidget handle) {
|
|||
MwFLFont font = NULL;
|
||||
MwPoint u_p, s_p, c_p;
|
||||
int u = 0, s = 0, c = 0;
|
||||
MwRect clip;
|
||||
|
||||
MwGetClipFrame(handle, &clip);
|
||||
|
||||
u_p.x = s_p.x = c_p.x = 0;
|
||||
u_p.y = s_p.y = c_p.y = 0;
|
||||
|
|
@ -76,9 +79,12 @@ static void draw(MwWidget handle) {
|
|||
case MwDOCUMENT_TEXT:
|
||||
{
|
||||
MwPoint p;
|
||||
int th2;
|
||||
|
||||
p.x = l->x;
|
||||
p.y = l->y + MwTextHeight(handle, font, l->text) / 2;
|
||||
p.y = l->y + (th2 = MwTextHeight(handle, font, l->text) / 2);
|
||||
|
||||
if((p.y + th2) <= clip.y || (p.y - th2) >= clip.y + clip.height) break;
|
||||
|
||||
if(u || s || c) {
|
||||
MwPoint line[2];
|
||||
|
|
@ -498,6 +504,7 @@ static void layout(MwWidget handle) {
|
|||
MwFLFont* fontstack = NULL;
|
||||
MwRect clickable;
|
||||
char* c_title = NULL;
|
||||
MwRect size;
|
||||
|
||||
arrput(fontstack, NULL);
|
||||
|
||||
|
|
@ -612,8 +619,9 @@ static void layout(MwWidget handle) {
|
|||
l->font = TOPFONT;
|
||||
}
|
||||
|
||||
y += MwTextHeight(handle, TOPFONT, "M");
|
||||
MwDispatchUserHandler(handle, MwNlayoutHandler, &y);
|
||||
size.width = w;
|
||||
size.height = y + MwTextHeight(handle, TOPFONT, "M");
|
||||
MwDispatchUserHandler(handle, MwNlayoutHandler, &size);
|
||||
|
||||
arrfree(fontstack);
|
||||
|
||||
|
|
|
|||
|
|
@ -351,13 +351,22 @@ static int vulkan_surface_setup(MwWidget handle, vulkan_t* o) {
|
|||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
LOAD_VK_FUNCTION(vkCreateWaylandSurfaceKHR);
|
||||
|
||||
VkWaylandSurfaceCreateInfoKHR createInfo = {
|
||||
VkWaylandSurfaceCreateInfoKHR createInfo;
|
||||
|
||||
/* transition to a subsurface */
|
||||
MwLLBeginStateChange(handle->lowlevel);
|
||||
handle->lowlevel->wayland.changing = MwTRUE;
|
||||
handle->lowlevel->wayland.type_to_be = MwLL_WAYLAND_SUBSURFACE;
|
||||
MwLLEndStateChange(handle->lowlevel);
|
||||
|
||||
createInfo = (VkWaylandSurfaceCreateInfoKHR){
|
||||
.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.display = handle->lowlevel->wayland.display,
|
||||
.surface = handle->lowlevel->wayland.framebuffer.surface,
|
||||
};
|
||||
|
||||
VK_CMD(_vkCreateWaylandSurfaceKHR(o->vkInstance, &createInfo, NULL, &o->vkSurface));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -609,6 +618,7 @@ void MwVulkanConfigure(MwVulkanConfig* cfg) {
|
|||
}
|
||||
|
||||
int MwVulkanSupported(void) {
|
||||
printf("[vulkan support not copmiled]\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue