Custom GTK widget to bypass GTK layout engine?
I have an application layer that I'd like to port to Gtk that has all it's own layout code and I don't really want to spend 'n' months re-writing it to work with the Gtk layout system, but rather just using the existing internal layout code and have Gtk render the resulting widgets.
I've started by writing my own widget after trying several of the built in containers. Basically I'm looking for something like the GtkFixed container that doesn't have a minimum size, i.e. Gtk will fit the first widget to the entire window, and all the child widgets will lay themselves out so that they fill the area. If I use GtkFixed for that, the window is always limited to the size of the initial layout, as that's the "requested" space. I can't resize it smaller than that using the edges of the window decor.
Maybe I need schooling in allocation vs requesting. My googling so far hasn't found the information I need to make this work. I did try.
I'm using the C API at the moment, and I'm targeting Win32 and Linux. So far I have a shell app working in Win32 that puts up an empty window. But the first child widget is limiting the resizing to it's 开发者_运维技巧initial size.
Edit: FYI the end result of all this is available here. That code represents the base widget that I can move and resize independent of GTKs layout engine.
I believe you want to use a GtkFixed
and connect to the size-request
signal on it, which gets called whenever the widget is asked to figure out how much space it wants. Modify the GtkRequisition
struct to be however much space you want the widget to have. This will be the amount of space the GTK layout engine tries to allocate to the widget if possible, so it's essentially the minimum size you want the widget to have. The layout engine, of course, is free to allocate more (or less!) space than you request.
The problem with my code is that I was catching the "configure-event" and returning TRUE, which stopped some of the normal GTK layout stuff from working. I need that event to update my internal size variables, but I also need to return FALSE to allow the next handler to get that signal.
Now my widget can assume the size of client area of the window correctly and I can then use GtkFixed style positioning to layout my controls where I need them to go.
One solution may be to subclass a widget to make it lying to the parents regarding its preferred/minimum size:
// here is where we are reckless about our content's size
static void reckless_fixed_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
*minimal = *natural = 1;
}
//here too
static void reckless_fixed_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
*minimal = *natural = 1;
}
The full code is for a slightly different usecase, which however fits here as well:
https://stackoverflow.com/a/49586044/817019
精彩评论