diff --git a/WINGs/wfont_wl.c b/WINGs/wfont_wl.c index 084b8e0..99ad0f5 100644 --- a/WINGs/wfont_wl.c +++ b/WINGs/wfont_wl.c @@ -164,7 +164,7 @@ wl_draw_string(void *sctx, void *handle, WMDrawable d, }; pango_ft2_render_layout(&bm, h->layout, 0, 0); - blit_alpha_to_pixman(dst, buf, stride, pw, ph, x, y - h->ascent, r, g, b, a); + blit_alpha_to_pixman(dst, buf, stride, pw, ph, x, y, r, g, b, a); wfree(buf); } diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 9aff056..9d3f194 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -3683,11 +3683,25 @@ wl_frame_configure(WNativeWindow win, int x, int y, int width, int height) struct wl_frame_buf *fb = frame_buf_find(win); if (!fb) return; - fb->x = x; - fb->y = y; + /* x,y are relative to parent for child windows */ + fb->rel_x = x; + fb->rel_y = y; + if (fb->parent_id) { + struct wl_frame_buf *parent = frame_buf_find(fb->parent_id); + if (parent) { + fb->x = parent->x + x; + fb->y = parent->y + y; + } else { + fb->x = x; + fb->y = y; + } + } else { + fb->x = x; + fb->y = y; + } if (fb->scene_buf) - wlr_scene_node_set_position(&fb->scene_buf->node, x, y); + wlr_scene_node_set_position(&fb->scene_buf->node, fb->x, fb->y); /* Resize: reallocate the pixman image if dimensions changed. */ if (width > 0 && height > 0 && (width != fb->width || height != fb->height)) { @@ -3729,17 +3743,36 @@ wl_frame_paint(struct WFrameWindow *fwin) /* --- Titlebar --- */ if (fwin->titlebar && fwin->top_width > 0) { - int tb_w = total_w; + struct wl_frame_buf *tb_fb = frame_buf_find(fwin->titlebar->window); + pixman_image_t *tb_img = tb_fb ? tb_fb->image : fb->image; + int tb_w = total_w; /* always full frame width */ int tb_h = fwin->top_width; + + /* Ensure titlebar buffer is full width */ + if (tb_fb && tb_fb->width < tb_w) { + pixman_image_unref(tb_fb->image); + tb_fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, + tb_w, tb_h, NULL, 0); + tb_fb->width = tb_w; + tb_fb->height = tb_h; + tb_fb->base.width = tb_w; + tb_fb->base.height = tb_h; + tb_img = tb_fb->image; + } WTexture *tex = fwin->title_texture[state]; + /* Clear titlebar buffer */ + if (tb_fb) { + pixman_color_t clear = {0, 0, 0, 0}; + pixman_image_fill_rectangles(PIXMAN_OP_SRC, tb_img, &clear, + 1, &(pixman_rectangle16_t){0, 0, tb_w, tb_h}); + } + /* Render texture to RImage. */ RImage *img = wTextureRenderImage(tex, tb_w, tb_h, WREL_RAISED); if (img) { - /* Blit RImage into the pixman buffer at (0, 0). - * RImage is RGBA (4 bytes/pixel) or RGB (3 bytes/pixel). */ - uint32_t *dst = pixman_image_get_data(fb->image); - int dst_stride = pixman_image_get_stride(fb->image) / 4; + uint32_t *dst = pixman_image_get_data(tb_img); + int dst_stride = pixman_image_get_stride(tb_img) / 4; int x, y; if (img->format == RRGBAFormat) { for (y = 0; y < tb_h && y < img->height; y++) { @@ -3796,12 +3829,15 @@ wl_frame_paint(struct WFrameWindow *fwin) } ty = (tb_h - th) / 2; - /* Draw text into the frame buffer using WMDrawable = pixman_image_t* */ - WMDrawString(fwin->screen_ptr->wmscreen, (WMDrawable)fb->image, + WMDrawString(fwin->screen_ptr->wmscreen, (WMDrawable)tb_img, fwin->title_color[state], *fwin->font, tx, ty, title, titlelen); wfree(title); } + + /* Commit titlebar buffer */ + if (tb_fb && tb_fb->scene_buf) + wlr_scene_buffer_set_buffer(tb_fb->scene_buf, &tb_fb->base); } /* --- Titlebar buttons --- */ @@ -3862,9 +3898,13 @@ wl_frame_paint(struct WFrameWindow *fwin) } } - /* Commit the buffer to the scene graph. */ - if (fb->scene_buf) - wlr_scene_buffer_set_buffer(fb->scene_buf, &fb->base); + /* Commit the buffer to the scene graph only if it has content (resizebar). */ + if (fb->scene_buf) { + if (fwin->resizebar && fwin->bottom_width > 0) + wlr_scene_buffer_set_buffer(fb->scene_buf, &fb->base); + else + wlr_scene_node_set_enabled(&fb->scene_buf->node, false); + } return 1; } @@ -6257,8 +6297,11 @@ static void wl_frame_paint_button(WCoreWindow *button, WTexture *texture, return; struct wl_frame_buf *frame_fb = frame_buf_find(fwin->core->window); + struct wl_frame_buf *tb_fb = fwin->titlebar ? frame_buf_find(fwin->titlebar->window) : NULL; struct wl_frame_buf *btn_fb = frame_buf_find(button->window); - if (!frame_fb || !frame_fb->image || !btn_fb) + /* Render into titlebar buffer if available, else frame buffer */ + struct wl_frame_buf *target = (tb_fb && tb_fb->image) ? tb_fb : frame_fb; + if (!target || !target->image || !btn_fb) return; int bx = btn_fb->rel_x; @@ -6283,18 +6326,18 @@ static void wl_frame_paint_button(WCoreWindow *button, WTexture *texture, return; /* Blit icon centered in button area */ - uint32_t *dst = pixman_image_get_data(frame_fb->image); - int dst_stride = pixman_image_get_stride(frame_fb->image) / 4; + uint32_t *dst = pixman_image_get_data(target->image); + int dst_stride = pixman_image_get_stride(target->image) / 4; int ix = bx + (bw - icon->width) / 2 + (pushed ? 1 : 0); int iy = by + (bh - icon->height) / 2 + (pushed ? 1 : 0); for (int y = 0; y < icon->height; y++) { int dy = iy + y; - if (dy < 0 || dy >= frame_fb->height) continue; + if (dy < 0 || dy >= target->height) continue; uint32_t *dst_row = dst + dy * dst_stride; for (int x = 0; x < icon->width; x++) { int dx = ix + x; - if (dx < 0 || dx >= frame_fb->width) continue; + if (dx < 0 || dx >= target->width) continue; unsigned char r, g, b, a; if (icon->format == RRGBAFormat) { int off = (y * icon->width + x) * 4; @@ -6311,8 +6354,8 @@ static void wl_frame_paint_button(WCoreWindow *button, WTexture *texture, } } - if (frame_fb->scene_buf) - wlr_scene_buffer_set_buffer(frame_fb->scene_buf, &frame_fb->base); + if (target->scene_buf) + wlr_scene_buffer_set_buffer(target->scene_buf, &target->base); } static void wl_noop_netwm_init(WScreen *scr) { (void)scr; } @@ -6464,7 +6507,7 @@ static void wl_appicon_paint(WAppIcon *aicon) strlen(icon->icon_name)); int tx = (size - tw) / 2; if (tx < 2) tx = 2; - int ty = fh; /* baseline near top */ + int ty = 0; /* top of text area */ WMColor *color = scr->icon_title_color; if (color) WMDrawString(scr->wmscreen, d, color, scr->icon_title_font, @@ -6662,14 +6705,14 @@ static void wl_menu_paint_entry(WMenu *menu, int index, int selected) WMDrawable d = (WMDrawable)(uintptr_t)fb->image; if (entry->text && font && color) { - int text_y = y + 3 + WMFontHeight(font) - 1; + int text_y = y + 3; WMDrawString(scr->wmscreen, d, color, font, 8, text_y, entry->text, strlen(entry->text)); } if (entry->rtext && entry->cascade < 0 && font && color) { int tw = WMWidthOfString(font, entry->rtext, strlen(entry->rtext)); - int text_y = y + 3 + WMFontHeight(font) - 1; + int text_y = y + 3; WMDrawString(scr->wmscreen, d, color, font, w - 8 - tw, text_y, entry->rtext, strlen(entry->rtext)); } @@ -6832,7 +6875,7 @@ static void wl_frame_paint_titlebar(WFrameWindow *fwin, int state) default: x = (fb->width - tw) / 2; break; } int fh = WMFontHeight(*fwin->font); - int y = (fb->height - fh) / 2 + fh; + int y = (fb->height - fh) / 2; WMDrawable d = (WMDrawable)(uintptr_t)fb->image; WMDrawString(scr->wmscreen, d, fwin->title_color[state],