Compare commits

..

38 commits

Author SHA1 Message Date
4e2c270908 ok
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-22 11:16:12 +09:00
cdf7657b19 ok 2026-09-22 11:16:12 +09:00
7d2b5a17a4 o 2026-09-22 11:16:12 +09:00
9bdd80b421 fix watcom 2026-09-22 11:16:12 +09:00
dfa8c22f1a fix 2026-09-22 11:16:12 +09:00
21911dd899 Update examples/dxdemos/CMakeLists.txt 2026-09-22 11:16:12 +09:00
e7dc38175f experiment with cmake not trying to find directx 2026-09-22 11:16:12 +09:00
7f361b9d15 correct names 2026-09-22 11:16:12 +09:00
ec45c8828d rename 2026-09-22 11:16:12 +09:00
83eb8c8dc4 ok 2026-09-22 11:16:12 +09:00
c5330cc184 direct3d9 2026-09-22 11:16:11 +09:00
12b89aab9b Update Jenkinsfile 2026-09-22 11:15:58 +09:00
e967523063 Update pl/rules.pl 2026-09-22 11:15:58 +09:00
aef5fe03a9 Update configure 2026-09-22 11:15:58 +09:00
a0da41210a Update configure 2026-09-22 11:15:58 +09:00
fb9919de2a oh wait the jenkinsfile can at least use enable-d3d 2026-09-22 11:15:58 +09:00
a18ca58f18 xml 2026-09-22 11:15:57 +09:00
f89eaf6901 put nul in gitignore for watcom cross compile 2026-09-22 11:15:01 +09:00
2f3b8f2417 error handling for d3d8 and d3d9 2026-09-22 11:15:01 +09:00
5872c43539 have watcom check for d3d8.h/d3d9.h 2026-09-22 11:15:01 +09:00
2a19c5e5cf genmk 2026-09-22 11:15:01 +09:00
87cbb582f7 perl 2026-09-22 11:15:01 +09:00
47c9f8df4e d3d8 too 2026-09-22 11:15:00 +09:00
bc326491b5 dx9 2026-09-22 11:15:00 +09:00
960db8d3e3 some fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-22 10:13:08 +09:00
c2f8fb3f82 wayland: actual subsurface type for the one widget that needs it (vulkan)
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 17:22:15 -07:00
e43a5291f5 combobox fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 16:55:27 -07:00
58027c095f snapshot previous buffer so that we don't have ghosting anymore on rotate (this also makes resizing A Bit better)
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 16:51:46 -07:00
cb5efd9224 wayland: got resizing looking good enough
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 15:49:01 -07:00
954a4a8e15 disable dnd on X11 for now
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 14:27:03 -07:00
9420878b93 oops! fix csd not working
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-21 12:01:23 -07:00
e8d692f05a remove the unneeded 'wayland event start/end' macros
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 11:54:07 -07:00
4cb88fdc05 wayland: remove our widget from parent's currently held widgets on destroy
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 11:40:51 -07:00
b1a2d4d549 wayland fixes
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 11:36:08 -07:00
f8c678ac53 ok
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 12:41:56 +09:00
2858679cc4 optimize
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 11:57:37 +09:00
39dd112f2b improve callback
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-21 11:47:44 +09:00
2b15e7e0a3 introducde underline and strikethrough
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-18 13:11:42 +09:00
18 changed files with 370 additions and 138 deletions

View file

@ -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

View file

@ -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() {

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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 */
/*!

View file

@ -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;

View file

@ -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"

View file

@ -204,7 +204,7 @@
<string />
</handler>
<handler name="layout">
<integer pointer="yes" />
<struct defname="MwRect" pointer="yes" />
</handler>
</handlers>
<enumerations>

View file

@ -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);
}

View file

@ -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
}

View file

@ -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);

View file

@ -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) {

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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