andreldm / xfwm4-theme-generator

Creates xfwm4 themes from client side decorations.
GNU General Public License v2.0
23 stars 4 forks source link

Using libmetacity to draw decorations #5

Open ging-dev opened 2 years ago

ging-dev commented 2 years ago

example:

#include <gtk/gtk.h>
#include <libmetacity/meta-theme.h>

MetaButtonState state = META_BUTTON_STATE_NORMAL;

MetaFrameFlags flags = META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU |
    META_FRAME_ALLOWS_MINIMIZE |
    META_FRAME_ALLOWS_MAXIMIZE | META_FRAME_ALLOWS_VERTICAL_RESIZE |
    META_FRAME_ALLOWS_HORIZONTAL_RESIZE | META_FRAME_ALLOWS_SHADE |
    META_FRAME_ALLOWS_MOVE;

MetaFrameType frame_type = META_FRAME_TYPE_NORMAL;

static MetaButtonState update_button_state (
    MetaButtonType type,
    GdkRectangle   rect,
    gpointer       user_data
) {
    return state;
}

static void create_png(
    gint client_width,
    gint client_height,
    MetaTheme *theme,
    gchar *filename
) {
    MetaFrameGeometry fgeom;

    meta_theme_calc_geometry(theme, NULL, frame_type, flags, client_width, client_height, &fgeom);

    gint width = client_width + fgeom.borders.total.left + fgeom.borders.total.right;
    gint height = client_height + fgeom.borders.total.top + fgeom.borders.total.bottom;

    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
    cairo_t *cr = cairo_create (surface);

    meta_theme_draw_frame(theme, NULL, cr, frame_type, flags, client_width, client_height,
        NULL, update_button_state, NULL, NULL, NULL
    );

    cairo_surface_write_to_png(surface, filename);
    cairo_destroy (cr);
    cairo_surface_destroy (surface);
}

int main(int argc, char **argv) {
    gtk_init(&argc, &argv);

    MetaTheme *theme = meta_theme_new(META_THEME_TYPE_GTK);
    meta_theme_set_button_layout(theme, ":minimize,maximize,close", FALSE);

    create_png(600, 400, theme, "1.png");
    flags |= META_FRAME_HAS_FOCUS;
    create_png(600, 400, theme, "2.png");
    state = META_BUTTON_STATE_PRELIGHT;
    create_png(600, 400, theme, "3.png");
    state = META_BUTTON_STATE_PRESSED;
    create_png(600, 400, theme, "4.png");

    return 0;
}
andreldm commented 2 years ago

Hi @ging-dev that's super cool, completely headless and hack-free!

Do you know if it's possible to get the geometry of buttons? Perhaps it's in MetaFrameGeometry, but I couldn't find libmetacity's documentation anywhere (I admit I'm lazy to read headers).

By the way, are you up to rewrite the whole thing using libmetacity? :sweat_smile:

ging-dev commented 2 years ago

Hi @ging-dev that's super cool, completely headless and hack-free!

Do you know if it's possible to get the geometry of buttons? Perhaps it's in MetaFrameGeometry, but I couldn't libmetacity's documentation anywhere (I admit I'm lazy to read headers).

By the way, are you up to rewrite the whole thing using libmetacity? sweat_smile

There doesn't seem to be a way to get the geometry of the button. It would be better to use it as window decorations directly in xfwm4

I found the above code in compiz: https://github.com/jaijeet/compiz/blob/master/gtk/window-decorator/gwd-theme-metacity.c

andreldm commented 2 years ago

I see, that's a pity, I'm wondering if we could get all the geometries from a real window, which may show up very briefly, then snap all images from the images generated by metacity.

There doesn't seem to be a way to get the geometry of the button. It would be better to use it as window decorations directly in xfwm4

That's the ultimate goal, Olivier already mentioned it makes sense to have this built-in Xfwm, perhaps using libmetacity would be ok for him as well. If you have an idea of how to implement this, please make a proposal in https://gitlab.xfce.org/xfce/xfwm4/-/issues/446 before committing time on something that may not be accepted.

matiasdelellis commented 3 months ago

Maybe we can use just gtk.. https://github.com/GNOME/metacity/blob/a0b41a8fb010b80477d134c97e0f3effd349a728/libmetacity/meta-theme-gtk.c#L662

😉

andreldm commented 2 months ago

Hi @matiasdelellis, thanks for the hint, I started a draft at #7, it's almost perfect for Greybird, only icons in the backdrop state are incorrect, Adwaita buttons are still not there and I didn't test scale 2x yet.

Another approach I'm considering is GtkOffscreenWindow, I'm already using it to get widget sizes, just taking screenshots of it isn't working for me.

Anyway, I need to set this aside for now, free time is really precious for me lately :grimacing: any help is more than welcome.