URI: 
       tMake button clipping work somewhat - ltk - Socket-based GUI for X11 (WIP)
  HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 8e162e7755e980a1f9bb03541201482b15fd89eb
   DIR parent dd010d6ac6864d58107799eb3625cdd4660684a1
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Sun, 24 Jan 2021 17:24:30 +0100
       
       Make button clipping work somewhat
       
       Diffstat:
         M button.c                            |      52 ++++++++++++++++++++++++-------
         M button.h                            |       2 +-
         M draw.c                              |      11 ++++-------
         M ltk.h                               |       1 +
         M ltkd.c                              |       3 +++
         M text.h                              |       2 +-
         M text_pango.c                        |       4 ++--
         M text_stb.c                          |       5 ++++-
       
       8 files changed, 57 insertions(+), 23 deletions(-)
       ---
   DIR diff --git a/button.c b/button.c
       t@@ -132,6 +132,15 @@ ltk_button_draw(ltk_button *button, ltk_rect clip) {
                /* no idea why it would be less than 0, but whatever */
                if (clip_final.w <= 0 || clip_final.h <= 0)
                        return;
       +        XCopyArea(window->dpy, button->pixmap, window->xwindow, window->gc,
       +            clip_final.x - rect.x, clip_final.y - rect.y,
       +            clip_final.w, clip_final.h, clip_final.x, clip_final.y);
       +}
       +
       +static void
       +ltk_button_redraw_pixmap(ltk_button *button) {
       +        ltk_window *window = button->widget.window;
       +        ltk_rect rect = button->widget.rect;
                int bw = theme.border_width;
                LtkColor *border;
                LtkColor *fill;
       t@@ -156,25 +165,42 @@ ltk_button_draw(ltk_button *button, ltk_rect clip) {
                        ltk_fatal("No style found for button!\n");
                }
                XSetForeground(window->dpy, window->gc, fill->xcolor.pixel);
       -        XFillRectangle(window->dpy, window->xwindow, window->gc, clip_final.x,
       -            clip_final.y, clip_final.w, clip_final.h);
       +        XFillRectangle(window->dpy, button->pixmap, window->gc, 0, 0, rect.w, rect.h);
                /* FIXME: Why did I do this? */
                if (bw < 1) return;
       -        /* FIXME: Maybe draw to tmp pixmap first, so this can be done properly? */
       -        /*
                XSetForeground(window->dpy, window->gc, border->xcolor.pixel);
                XSetLineAttributes(window->dpy, window->gc, bw, LineSolid,
                    CapButt, JoinMiter);
       -        XDrawRectangle(window->dpy, window->xwindow, window->gc,
       -            rect.x + bw / 2, rect.y + bw / 2, rect.w - bw, rect.h - bw);
       -        */
       +        XDrawRectangle(window->dpy, button->pixmap, window->gc,
       +            bw / 2, bw / 2, rect.w - bw, rect.h - bw);
        
                int text_w, text_h;
                ltk_text_line_get_size(button->tl, &text_w, &text_h);
       -        int text_x = rect.x + (rect.w - text_w) / 2;
       -        int text_y = rect.y + (rect.h - text_h) / 2;
       -        /* FIXME: Actually use button->text_pixmap */
       -        ltk_text_line_draw(button->tl, window->gc, text_x, text_y, clip_final);
       +        int text_x = (rect.w - text_w) / 2;
       +        int text_y = (rect.h - text_h) / 2;
       +        /* FIXME: Remove clipping rect from text line - this is just used here as a dummy
       +           because it is completely ignored */
       +        ltk_text_line_draw(button->tl, button->pixmap, window->gc, text_x, text_y, rect);
       +}
       +
       +/* FIXME: Make this amortised constant; make it generic for all widgets */
       +static void
       +ltk_button_resize(ltk_button *button) {
       +        Window win;
       +        int x, y, w, h, bw, d;
       +        int new_w, new_h;
       +        ltk_window *window = button->widget.window;
       +        ltk_rect rect = button->widget.rect;
       +        XGetGeometry(window->dpy, button->pixmap, &win, &x, &y, &w, &h, &bw, &d);
       +
       +        new_w = w < rect.w ? rect.w : w;
       +        new_h = h < rect.h ? rect.h : h;
       +        if (new_w < w && new_h < h)
       +                return;
       +        XFreePixmap(window->dpy, button->pixmap);
       +        button->pixmap = XCreatePixmap(window->dpy, window->xwindow,
       +            new_w, new_h, window->depth);
       +        ltk_button_redraw_pixmap(button);
        }
        
        static void
       t@@ -198,6 +224,7 @@ ltk_button_change_state(ltk_button *button) {
                        ltk_fatal("No style found for button!\n");
                }
                ltk_text_line_render(button->tl, fill, &theme.text_color);
       +        ltk_button_redraw_pixmap(button);
        }
        
        static int
       t@@ -215,6 +242,7 @@ ltk_button_create(ltk_window *window, const char *id, const char *text) {
                ltk_fill_widget_defaults(&button->widget, id, window,
                    &ltk_button_draw, &ltk_button_change_state, &ltk_button_destroy, 1, LTK_BUTTON);
                button->widget.mouse_release = &ltk_button_mouse_release;
       +        button->widget.resize = &ltk_button_resize;
                uint16_t font_size = window->theme.font_size;
                text_copy = strdup(text);
                if (!text_copy)
       t@@ -224,6 +252,8 @@ ltk_button_create(ltk_window *window, const char *id, const char *text) {
                ltk_text_line_get_size(button->tl, &text_w, &text_h);
                button->widget.ideal_w = text_w + theme.border_width * 2 + theme.pad * 2;
                button->widget.ideal_h = text_h + theme.border_width * 2 + theme.pad * 2;
       +        button->pixmap = XCreatePixmap(window->dpy, window->xwindow,
       +            button->widget.ideal_w, button->widget.ideal_h, window->depth);
                /* render text */
                ltk_button_change_state(button);
        
   DIR diff --git a/button.h b/button.h
       t@@ -29,7 +29,7 @@
        typedef struct {
                ltk_widget widget;
                LtkTextLine *tl;
       -        Pixmap text_pixmap;
       +        Pixmap pixmap;
        } ltk_button;
        
        void ltk_button_setup_theme_defaults(ltk_window *window);
   DIR diff --git a/draw.c b/draw.c
       t@@ -37,7 +37,7 @@
        static void ltk_draw_draw(ltk_draw *draw);
        static ltk_draw *ltk_draw_create(ltk_window *window,
            const char *id, int w, int h, const char *color);
       -static void ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h);
       +static void ltk_draw_resize(ltk_draw *draw);
        static void ltk_draw_destroy(ltk_draw *draw, int shallow);
        static void ltk_draw_clear(ltk_window *window, ltk_draw *draw);
        static void ltk_draw_set_color(ltk_window *window, ltk_draw *draw, const char *color);
       t@@ -79,7 +79,6 @@ ltk_draw_draw(ltk_draw *draw) {
        
        static ltk_draw *
        ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *color) {
       -        XWindowAttributes attrs;
                ltk_draw *draw = malloc(sizeof(ltk_draw));
                if (!draw) ltk_fatal_errno("Unable to allocate memory for ltk_draw.\n");
        
       t@@ -88,9 +87,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co
                draw->widget.resize = &ltk_draw_resize;
                draw->widget.rect.w = w;
                draw->widget.rect.h = h;
       -        XGetWindowAttributes(window->dpy, window->xwindow, &attrs);
       -        draw->depth = attrs.depth;
       -        draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, draw->depth);
       +        draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, window->depth);
                if (!ltk_create_xcolor(window, color, &draw->bg)) {
                        free(draw);
                        ltk_fatal_errno("Unable to allocate XColor.\n");
       t@@ -103,7 +100,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co
        }
        
        static void
       -ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h) {
       +ltk_draw_resize(ltk_draw *draw) {
                Window win;
                int x, y, w, h, bw, d;
                int new_w, new_h;
       t@@ -116,7 +113,7 @@ ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h) {
                if (new_w < w && new_h < h)
                        return;
                Pixmap tmp = XCreatePixmap(window->dpy, window->xwindow,
       -            new_w, new_h, draw->depth);
       +            new_w, new_h, window->depth);
                XSetForeground(window->dpy, window->gc, draw->bg.pixel);
                XFillRectangle(window->dpy, tmp, window->gc, 0, 0, new_w, new_h);
                XCopyArea(window->dpy, draw->pix, tmp, window->gc,
   DIR diff --git a/ltk.h b/ltk.h
       t@@ -139,6 +139,7 @@ typedef struct ltk_window {
                int screen;
                Atom wm_delete_msg;
                Window xwindow;
       +        int depth;
                ltk_widget *root_widget;
                ltk_widget *active_widget;
                ltk_widget *pressed_widget;
   DIR diff --git a/ltkd.c b/ltkd.c
       t@@ -581,6 +581,7 @@ ltk_window_other_event(ltk_window *window, XEvent event) {
        static ltk_window *
        ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int h) {
                char *theme_path;
       +        XWindowAttributes attrs;
        
                ltk_window *window = malloc(sizeof(ltk_window));
                if (!window)
       t@@ -601,6 +602,8 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int 
                    XCreateSimpleWindow(window->dpy, DefaultRootWindow(window->dpy), x, y,
                                        w, h, window->theme.border_width,
                                        window->theme.fg.xcolor.pixel, window->theme.bg.xcolor.pixel);
       +        XGetWindowAttributes(window->dpy, window->xwindow, &attrs);
       +        window->depth = attrs.depth;
                window->gc = XCreateGC(window->dpy, window->xwindow, 0, 0);
                XSetForeground(window->dpy, window->gc, window->theme.fg.xcolor.pixel);
                XSetBackground(window->dpy, window->gc, window->theme.bg.xcolor.pixel);
   DIR diff --git a/text.h b/text.h
       t@@ -10,7 +10,7 @@ void ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap 
        void ltk_cleanup_text(void);
        LtkTextLine *ltk_text_line_create(Window window, uint16_t font_size, char *text, int width);
        void ltk_text_line_render(LtkTextLine *tl, LtkColor *bg, LtkColor *fg);
       -void ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip);
       +void ltk_text_line_draw(LtkTextLine *tl, Drawable d, GC gc, int x, int y, ltk_rect clip);
        void ltk_text_line_set_width(LtkTextLine *tl, int width);
        void ltk_text_line_get_size(LtkTextLine *tl, int *w, int *h);
        void ltk_text_line_destroy(LtkTextLine *tl);
   DIR diff --git a/text_pango.c b/text_pango.c
       t@@ -98,8 +98,8 @@ ltk_text_line_render(LtkTextLine *tl, LtkColor *bg, LtkColor *fg) {
        }
        
        void
       -ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip) {
       -        XCopyArea(tm.dpy, tl->pixmap, tl->window, gc, 0, 0, tl->w, tl->h, x, y);
       +ltk_text_line_draw(LtkTextLine *tl, Drawable d, GC gc, int x, int y, ltk_rect clip) {
       +        XCopyArea(tm.dpy, tl->pixmap, d, gc, 0, 0, tl->w, tl->h, x, y);
        }
        
        void
   DIR diff --git a/text_stb.c b/text_stb.c
       t@@ -534,7 +534,8 @@ ltk_text_line_render(
        
        /* FIXME: error checking if img is rendered yet, tm initialized, etc. */
        void
       -ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip) {
       +ltk_text_line_draw(LtkTextLine *tl, Drawable d, GC gc, int x, int y, ltk_rect clip) {
       +        /*
                int xoff = clip.x - x;
                int yoff = clip.y - y;
                xoff = xoff >= 0 ? xoff : 0;
       t@@ -542,6 +543,8 @@ ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip) {
                int w = clip.w > tl->w - xoff ? tl->w - xoff : clip.w;
                int h = clip.h > tl->h - yoff ? tl->h - yoff : clip.h;
                XPutImage(tm.dpy, tl->window, gc, tl->img, xoff, yoff, x + xoff, y + yoff, w, h);
       +        */
       +        XPutImage(tm.dpy, d, gc, tl->img, 0, 0, x, y, tl->w, tl->h);
        }
        
        void