GTK3 Theming modGTK3 Resolves layout corruption under ALL Linux Distros

  1. ‹ Older
  2. 8 weeks ago

    Jürg O

    Sep 21 Pre-Release Testers, Xojo Pro

    @Jürg O 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.

    Today I've found a Theme that seems to work - it's "macOS like" styled:
    -image-
    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?) ;)

    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:
    -image-

    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... ;)

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

  3. Tim J

    Sep 21 Pre-Release Testers, Xojo Pro Dehydrating in AZ

    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?

  4. Jürg O

    Sep 21 Pre-Release Testers, Xojo Pro
    Edited 8 weeks ago

    @Tim J 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 :(
    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").

  5. Tanner L

    is not verified Sep 21 Pre-Release Testers Toronto, Canada

    @Jürg O 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.

    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).

  6. Pedro I

    Sep 21 Pre-Release Testers, Xojo Pro

    @Jürg O I googled how to do that, but haven't managed to get it working

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

    ComboBox

    ComboBoxText

  7. 7 weeks ago

    Jürg O

    Sep 23 Pre-Release Testers, Xojo Pro

    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).

  8. jim m

    Sep 24 Pre-Release Testers, Xojo Pro Phoenix, Arizona

    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
  9. Jürg O

    Sep 25 Pre-Release Testers, Xojo Pro

    Thanks, Jim.

    @jim m It fixes most things, but textareas and textfields (and in turn comboboxes) are clipped unless the width is >300 or so.

    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, … ;) 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 m: How is the clipping with TextFields/Areas if you're trying this style?

    It looks like this on my VM's:
    -image-

      //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
  10. jim m

    Sep 25 Pre-Release Testers, Xojo Pro Phoenix, Arizona

    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):
    -image-
    The progressbar is indeterminate type but the indicator is offscreen.

    Here's another bad one: (Cinnamox-WillowGrove theme)
    -image-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:
    -image-

  11. jim m

    Sep 25 Pre-Release Testers, Xojo Pro Phoenix, Arizona

    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:
    -image--image-
    -image-

  12. Tim J

    Sep 25 Pre-Release Testers, Xojo Pro Dehydrating in AZ

    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.

  13. Jürg O

    Sep 26 Pre-Release Testers, Xojo Pro

    @jim m Ok, I think I've found the issue with textfields.
    in the open event of a window, I put...
    and using this theme modification...

    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

    -image-

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

  14. Jürg O

    Sep 26 Pre-Release Testers, Xojo Pro

    @Jürg O 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 m: 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:
    -image-

    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?

  15. Jürg O

    Sep 26 Pre-Release Testers, Xojo Pro

    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?

  16. jim m

    Sep 26 Pre-Release Testers, Xojo Pro Phoenix, Arizona

    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...
    -image-

    Looking pretty good!
    -image-

  17. jim m

    Sep 26 Pre-Release Testers, Xojo Pro Phoenix, Arizona

    I just remembered my error message checking isn't done yet though...

  18. jim m

    Sep 26 Pre-Release Testers, Xojo Pro Phoenix, Arizona

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

  19. Jürg O

    Sep 27 Pre-Release Testers, Xojo Pro
    Edited 7 weeks ago

    @jim m Ok, I updated the example to include a syntax checking live editor.

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

    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:
    -image-

    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 :)

  20. Tim J

    Sep 28 Pre-Release Testers, Xojo Pro Dehydrating in AZ

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

    -image-

    100 thank you's for this win!

  21. Andre K

    Sep 29 Pre-Release Testers

    -image-

    Via VNC looking at the result of the GTK3 Theming result on a Pine64 running Ubuntu 16 LTS with Mate desktop. The VNC-server shows the result on the XFCE4-desktop. As you can see it looks great!

    Just as Tim says: many MANY thanks for this fine solution.:D

  22. Newer ›

or Sign Up to reply!