GTK3 Theming modGTK3 Resolves layout corruption under ALL Linux Distros

As my second post states, GTK is NOT designed to work in a fixed layout like apps in windows or Mac. So, the only way Xojo could fix this problem is to implement and expose the GTK native containers. But, doing that, they will break the multiplatform compatibility of the layout designer. So, not an easy solution.

But, Maybe if Xojo implement GTK in ALL 3 desktop platforms…

  • Lots of contros out of the box for xojo
  • Great Layout widgets to make modern interfaces
  • Awesome performance with hardware accelerated drawing
  • Consistency in all the 3 platforms
  • Cairo Drawing could be used to add PDF capabilities
  • Xojo team will focus in 1 UI instead of 3
  • Apps with themes in all the platforms.
  • Etc

Feedback Case 52860 - Implement the full GTK widget set and Cairo drawings on all 3 platforms for better multiplatform compatibility

Gimp On Windows

Gimp On Linux

Gimp On Mac

New Gimp style On Windows

New Gimp style On Windows other theme

Feedback Case 52860 - Implement the full GTK widget set and Cairo drawings on all 3 platforms for better multiplatform compatibility

1 Like

[quote=398564:@Jürg Otter]Xojo has recently posted a blog: GTK3 Can Be a Pain in the Themes
Has anyone tried to load a “built-in theme”? I tried, but… on Debian 9 (with both provided and some downloaded themes). The Controls (Buttons, TextFields, …) are still way too high - always.[/quote]
Today I’ve found a Theme that seems to work - it’s “macOS like” styled:

And it seems that this Theme allows to have Controls reasonably sized in MyControl.Height=26 - and it seems to work (Maybe even on RasPi?) :wink:

But since I don’t want our app to look “macOS like”, I’ve tried to extract just the Styles to get the Text alignment right, and Borders shown with Controls that are .Height=26.
So far, this is the result:

It’s working as expected for TextField and PushButtons. But what is going on with ComboBox and PopupMenu?
It has the same style applied such as TextField. So margins/insets/… are being applied. But it looks like ComboBox and PopupMenu are somehow “inside” it.

Does anyone know how to get the ComboBox and PopupMenu look the “same” as TextField and PushButton?

  • PopupMenu is quite similar to PushButton -> the Borders and TextAlignment could/should be the same
  • ComboBox is “like” a TextField (with something on the right) -> how to get it styled the same?

I’m sure the answer is in the (macOS like looking) “theme .css”. Because with that, the PopupMenu and ComboBox get styled in a way that the Text looks OK with ControlHeight 26. I just can’t find the right “enclosure”, as it seems that there needs to be some kind of “style the inside box like this, and style the arrows like that”.
I still hope to find a way to just style the very basics (that uses all the system default, except for .Height resulting vertical Text alignment) - and not having to provide a full-blown Theme… :wink:

If you’d like to try: The ScreenShots above have been taking by running this example project on Debian 9.

I suspect that the PopupMenu and ComboBox controls are custom controls that used combinations of other controls to create their effects.

Have you tried using the gtkinspector to see how those controls are actually built up?

I googled how to do that, but haven’t managed to get it working… So - no, unfortunately I don’t know how to do that :frowning:
That’s why I’m here and asking… I’m sure someone figures out how to “get inside” (and apply the Style to the “inside”).

[quote=406719:@Jürg Otter]It’s working as expected for TextField and PushButtons. But what is going on with ComboBox and PopupMenu?
It has the same style applied such as TextField. So margins/insets/… are being applied. But it looks like ComboBox and PopupMenu are somehow “inside” it.[/quote]

In the control’s open events I tried this:

Me.Style_Linux_GTK3_CSS = "min-height: 24px; min-width: 16px; border: 0px solid; border-radius: 5px; padding: 0 6px;"

This removed the black border, and affected the spacing slightly. Definitely an improvement. I tested on VM’s of Mint 18.3 and PopOS 18.04 LTS. PopOS did show an artifact - the combobox arrow icon wasn’t fully flush right (similar to your original pic).

The PopupMenu and ComboBox are the native Gtk.ComboBox and Gtk.ComboBoxText. And they are made up of other widgets:

ComboBox

ComboBoxText

Thanks for trying. I know that the gtk3 documentation probably contains all the required bits and pieces - especially the CSS nodes. It seems to me that I still don’t know how to properly address the sub-levels in the example, as there are no Xojo-specific CSS examples. A simple “Color” change is working in other Controls, but not in ComobBox/PopupMenu. I know, I’ve tried a “Control based” approach, not a global style.
But even then - now that I have some Controls looking good with Debian 9 (e.g. a TextField with the desired height), they appear much different on Ubuntu (much too tiny with the same “style”).
So I guess it’s a “you have to style for each Distribution/whatever” kind of thing. Not really what we are looking for. Not what gtk2 has been - that has been looking ok and acceptable everywhere. I’m giving up again (for now).

I’ve been digging around a LOT in gtk3 lately.

Here’s some code to try in your app.open event. It fixes most things, but textareas and textfields (and in turn comboboxes) are clipped unless the width is >300 or so. Big improvement though. (some themes may still clip buttons slightly)

#if TargetLinux
  const style="GtkButton, GtkEntry, button, entry, .button, .entry " _
  +"{padding:0px;margin:1px;margin-top:0px; min-height:14px;min-width:14px} " _
  +"scrollbar.horizontal slider{min-height:8px} scrollbar.vertical slider(min-width:8px;}" _
  +"progressbar trough{min-width:10px; min-height:10px;}"
  
  
  const klibgtk = "libgtk-3"
  declare Function gdk_display_get_default lib klibgtk () as ptr
  declare Function gdk_display_get_default_screen lib klibgtk (display as ptr) as ptr
  declare Function gtk_css_provider_new lib klibgtk () as ptr
  declare Function gtk_css_provider_load_from_data lib klibgtk (obj as ptr,data as CString,length as uint32,error as ptr) as Boolean
  declare sub gtk_style_context_add_provider_for_screen lib klibgtk (screen as ptr, provider as ptr, priority as int32)
  
  dim screen as ptr=gdk_display_get_default_screen(gdk_display_get_default)
  dim provider as ptr=gtk_css_provider_new
  call gtk_css_provider_load_from_data(provider,style,-1,nil)
  gtk_style_context_add_provider_for_screen(screen,provider,900)
#endif

Thanks, Jim.

I’ve tried to find a “one size that fits them all” (for both Debian and Ubuntu). But that doesn’t seem to work out well - something is always wrong - too tiny, clipped, cut-off, wrong indent/padding, … :wink: And still I’d like to adjust as little as possible.

So here’s my next approach - you’ll find it in this example project:

  • I’ve split GtkEntry and GTKButtons - so that they can have a different padding
  • In my tests, especially Ubuntu 16 needed some special treatment (TextFields have been tiny in Height otherwise). I wonder if there is a “more generic” approach to figure out what’s different here? Right now I’m just looking at the lsb_release -d Description and define other padding for Ubuntu 16.04

@jim mckay: How is the clipping with TextFields/Areas if you’re trying this style?

It looks like this on my VM’s:

[code] //Debian 9, Ubuntu 14, Ubuntu 18
Dim sDefaultPadding_Entry As String = “1px”
Dim sDefaultPadding_Button As String = “1px”

//Ubuntu 16.04: TextFields are tiny in height - needs more padding
if (InStr(Linux_OS_Description, “Ubuntu 16.04”) > 0) then
sDefaultPadding_Entry = “3px”
sDefaultPadding_Button = “1px”
end if

Dim sStyleCSS As String = _
"GtkEntry, entry, .entry {min-height: 22px; min-width: 16px; margin: 0px; padding: " + sDefaultPadding_Entry + "; padding-left: 5px; padding-right: 5px;} " + _
"GtkButton, button, .button {min-height: 22px; min-width: 16px; margin: 0px; padding: " + sDefaultPadding_Button + "; padding-left: 5px; padding-right: 5px;} "

modTest.GTK3_GlobalStyleCSS = sStyleCSS[/code]

Be sure to add scrollbars and a progressbar to your test. If the progressbar width is less that about 150 pixels, it gets clipped on the right. That’s why I was setting min-width on it though it seems to not be working now. Scrollers also clip on some themes.

High Contrast is still pretty bad (without the min-width min-height on scrollbars):

The progressbar is indeterminate type but the indicator is offscreen.

Here’s another bad one: (Cinnamox-WillowGrove theme)
See how the buttons just don’t fit. Also the text field is clipped badly along with the combobox.

Default Mint-Y theme isn’t bad but textfields still get clipped on the right:

Ok, I think I’ve found the issue with textfields. There is a property “width-chars” that is used to size the entry. It defaults to -1 which means to use all available space. If it is set to 0 then the control sizes normally.

So in the open event of a window, I put this:

#if TargetLinux declare sub g_object_set Lib "libgtk-3" (obj as ptr, name as CString, value as int32,term as ptr=nil) declare Function gtk_bin_get_child Lib "libgtk-3" (obj as ptr) as ptr for i as integer=0 to ControlCount-1 if Control(i) isa TextField then dim t As TextField=TextField(control(i)) g_object_set(ptr(t.Handle),"width-chars",0) end if if Control(i) isa ComboBox then dim c as ComboBox=ComboBox(control(i)) dim t as ptr=gtk_bin_get_child(ptr(c.Handle)) g_object_set(t,"width-chars",0) end if next #endif

and using this theme modification:

Dim sStyleCSS As String = _ "GtkButton, button {padding:0px;margin:0px; min-height:18px; min-width:18px} " _ +" entry{margin:0px;padding-top:0px;padding-bottom:0px;min-height:1px;} " _ +"scrollbar.horizontal trough slider{min-height:8px} scrollbar.vertical trough slider{min-width:8px;} " _ +"progressbar trough {min-width:1px;}"

I get:

Hi Jim - excellent sleuthing on your part. From a quick check on my end, we just need to add that to each window’s Constructor and things can be a saner world under Linux.

[quote=407371:@jim mckay]Ok, I think I’ve found the issue with textfields.
in the open event of a window, I put…
and using this theme modification…[/quote]
Then I get this on Ubuntu:

  • DropDown Arrows on Ubuntu 18 are too far right
  • TextField is clipped on bottom on Ubuntu 16
  • PopupMenu: Text is too far left on both Ubuntu 18 and 16

I’ll try to mix both approaches together - let’s see what it turns out on various distributions…

So here’s an example project where I’ve tried to combine it all:

  • modGTK3: all Declares are in here
  • 1 global style (initialized in App.Open) (a mix of Jim and Jürg, now containing the Scrollbar style settings)
  • Controls are Subclasses - they call InitGTK3Control (to set the width-chars=0, and make sure their Height is 26). In our real-world projects, we’re always using subclasses for Controls, so that we can easily and globally modify them with each Xojo version. I don’t like to copy-paste code in all Window’s Constructors (or other places) - I prefer once central place. Oh, and yes - I know - in this example, the ScrollBar’s aren’t subclassed.

@jim mckay: The DropDown arrows and PopupMenu TextAlignment looks better to me on Ubuntu now. If you’re running this example project as it is - do you still get the clipped TextFields on your Mint distributions? Or has your included width-chars=0 fixed that?

It looks like this on the Distributions I have at hand:

Hopefully we can figure out a style combination that works acceptable on all “most common” distributions… for me Ubuntu and Debian are part of that, and Ubuntu is where Jim’s previous style hasn’t worked out well. So I’m wondering if this “mix” is looking good not only on Ubuntu, but Mint as well?

Hmm, I’ve updated the example above: By pressing the PushButton, it shows MessageDialog, and to confirm it shows a MessageBox. Just why are the Buttons in these Message(Box) dialogs cut off, so that the bottom border is not fully visible (Ubuntu 14 and 16; Ubuntu 18 and Debian are OK)?
It seems to me the difference is that Debian and Ubuntu 18 are using a kind of “use full with” layout for these buttons, which can be styled with messagedialog .dialog-action-area button { } . But Ubuntu 14/16 are just placing buttons in the “bottom-right area”. And in this case, the dialog-action-area doesn’t seem to have any effect. Still - the Buttons are clipped, but why…? The ones on the main window are ok, but those on MsgBox/Dialog not?

Ok, I updated the example to include a syntax checking live editor.
I did switch things around so the global setter returns a boolean to indicate success And added an error info class…

Looking pretty good!

I just remembered my error message checking isn’t done yet though…

Ok, fixed the error messages… Now it will give something meaningful.
Here’s the example.

Cool, thanks! That makes it much more convenient to try different things :slight_smile:

I’ve updated the example to “v5” - you can get it here: 5_Linux-gtk3-style-test.zip

Notes to the changes:

  • The “global GTK3 Style” is no longer in a Constant. It’s now an Array. Why? For one, the various stylings can be “split”. It makes it easier to add a default set, but in a dynamic way (e.g.: “Ubuntu 16.04” needs this part-style, too). And I’ve found that for example Ubuntu 14 can’t parse “min-height/width”. So this Array is now being fed to be initialized one-by-one. The style-parts that won’t work in the current distribution get ignored, all the rest gets applied.
  • You see the result of this in the global String variable: GlobalGTK3CSS - and this is shown in your cool GTK3 CSS live editor. So it no longer contains the parts that can’t be parsed anyway.
  • I have found a way to get the Buttons in MessageDialogs and MsgBoxes look good on Ubuntu 14, 16 - style is included in the example
  • Ubuntu 14 doesn’t use the global “button” and “entry” styles, only “.button” and “.entry” - that’s why both are in the list again
  • The Scrollbar Styles don’t seem necessary on Ubuntu and Debian, so I’ve commented them out. In fact - the Scrollbars look worse on Ubuntu with the style applied. How about Mint? Can you create two screenshots with/without? Otherwise it might be good to figure out what environment needs this, so that an application can add this dynamically… (similar to my “Ubuntu 16.04” TextField-fix). It would be great to come up with a “default global style set” that works on all Mint, Debian, Ubuntu (and others).

Here’s what 5_Linux-gtk3-style-test.zip looks like on Debian and Ubuntu:

Oh, and just for fun: I’ve set Height=24 for the Controls in modGTK3.InitGTK3Control. And it looks acceptable - I certainly couldn’t have this “small Height (for Linux standards)” before - not with Xojo’s default implementation :slight_smile:

One of my toughest targets is Fedora/CentOS with the default desktop settings. Your efforts kick its behind!!!

100 thank you’s for this win!