This Week in GTK+ – 15

In this last week, the master branch of GTK+ has seen 60 commits, with 10838 lines added and 6850 lines removed.

Planning and status
  • We’re close to the GTK+ 3.22 release, in time for GNOME 3.22.
  • Emmanuele has implemented a more comprehensive fallback path for mixed widget trees in his GSK branch.
  • Timm Bäder has taken the initial port of the build system to Meson done at GUADEC by Jussi Pakkanen and improved upon it.
  • The GTK+ road map is available on the wiki.
Notable changes
  • Carlos Garnacho merged his branch that implements graphic tablet support for the Wayland GDK backend; more details are available on his blog.
  • Jonas Ådahl ported GDK to the 6th version of the Wayland xdg_shell protocol, and he also fixed the behavior of transient-for windows created by sandbox portals on Wayland.

Bugs fixed

  • 770236 gtkbindings: Add an example for gtk_binding_entry_add_signal()
  • 770026 review comments for wip/wayland-tablet-v2
  • 770332 Notebook arrow icon wrong color after creating new tab
  • 769937 wayland: Port backend to use xdg-shell unstable v6
  • 764413 Wayland: not fullscreenable gtk+ apps can be fullscreened
  • 770374 Gtk Treeview Editable overshoots column width when column width is small
  • 770550 gtkplacessidebar: fix signal marshal
  • 770458 GtkAboutDialog issue with long credit lists and GtkScrolledWindow
  • 769788 Fix stacking order of flatpak portals on Wayland
Getting involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 14

In these last two weeks, the master branch of GTK+ has seen 48 commits, with 4967 lines added and 3798 lines removed.

Planning and status
  • We skipped last week’s update due to most of the GTK+ developers being at GUADEC.
  • We had very productive discussions regarding the new release management and versioning scheme going forward; expect a full announcement on this blog.
  • GSK has been reviewed during GUADEC, and the work on the conversion of widgets to the new retained rendering API is ongoing; the API won’t be merged for 3.22, in order to improve rendering performance, shake out the last API issues found during porting, and especially avoid last minute breaking of applications using their own rendering on top of GTK+ windows, like Firefox and LibreOffice.
  • Carlos Garnacho has been porting the Wayland backend to the new tablet protocol; various changes have already landed in master, and the bulk of the review process is in bug 770026.
  • The work to support HiDPI displays in the Windows backend is progressing in bug 768081.
  • The GTK+ road map is available on the wiki.
Notable changes
  • Andreas Pokorny has been updating the Mir backend for GDK to improve the integration of GTK+ applications.
  • Timm Bäder added two new methods to GtkPopover, gtk_popover_popup() and gtk_popover_popdown(); these two new methods implement animated transitions, while calling gtk_widget_show() and gtk_widget_hide() will immediately show or hide the GtkPopover. With the addition of these two new methods, the GtkPopover:transitions-enabled property is now redundant and has been deprecated.

Bugs fixed

  • 769603 gtk+-3.20.8: underlink issue with ld.gold – build fails: ./.libs/libgdk-3.so: error: undefined reference to ‘shm_open’
  • 769601 Dead link in faq on gtk-question-index.html
  • 769568 Modification date display incorrectly wraps calendar days (and is inconsistent with GTK2 and Nautilus)
  • 768138 Update the GDK-Mir backend to fix a few problems
  • 769706 Add show/hide API to GtkPopover
  • 769402 regression in menu positioning on wayland
  • 768017 [Wayland] menus opened from access keys (mnemonic menu items) hide instantly
Getting involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 13

In this last week, the master branch of GTK+ has seen 29 commits, with 4141 lines added and 3230 lines removed.

Planning and status
Notable changes
  • Ruslan Izhbulatov fixed two long standing issues with the keyboard layout and dead keys handling on Windows. GTK+ applications on Windows should now behave more in line with the rest of the platform, especially on US international keyboards. The changes have been applied to the master branch, but after further testing they should be backported to the 2.x stable branch.

Bugs fixed

  • 769287 GtkMenuToolButton:show-menu is emitted twice and breaks dynamic menus
  • 769485 Eliminate use of g_test_expect_message()
  • 712760 Clang static analysis fixes
  • 769451 Build failure of 3.21 (master) in Debian Unstable since 7-26-2016
Getting involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 12

In this last week, the master branch of GTK+ has seen 28 commits, with 1868 lines added and 1422 lines removed.

Planning and status
Notable changes
  • Georges Basile Stavracas Neto has made the formerly private GtkShortcutLabel widget, used by the shortcuts window, part of the public API; the widget will be used in the GNOME Control Center keyboard options, and can be used by applications that allow editing their own keyboard shortcuts, like PiTiVi.

Bugs fixed

  • 768999 Floating point exception (division by zero) when running under Xvfb
  • 768930 reftests: override GSETTINGS_SCHEMA_DIR when running tests
  • 760944 resizing and geometry (snap to character cells) regressed with Gtk 3.19+
  • 755947 wayland: gnome-terminal does not fill entire area when tiled
  • 769047 GtkWidget <-> GtkStyleContext API not clear
  • 769205 Expose GtkShortcutLabel as a public widget
  • 769004 css test suite failures in 3.21.4
  • 768902 Font too small when using gtk_widget_override_font()
  • 769126 Can’t type astral plane characters into a GtkEntry using the Windows 10 touch keyboard
  • 769236 demos: Fix build failure
Getting involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 11

In this last week, the master branch of GTK+ has seen 22 commits, with 6199 lines added and 1763 lines removed.

Planning and status
  • Matthias Clasen released GTK+ 3.21.4 and GLib 2.49.4, two new developers’ snapshots.
Notable changes
  • William Hua started merging the patches for relative positioning of menus and popups in the master branch.
  • Lapo Calamandrei did a small visual refresh of the styling of GtkCalendar in Adwaita.
  • Carlos Garnacho updated GDK to use the 2.0 version of the Wayland graphics tablet input protocol.
  • Matthias Clasen updated GTK+ to opt into the new structured logging API provided by GLib.

 

Bugs fixed

  • 769003 Adwaita: GtkCalendar uses a confusing style for week of year
  • 756579 GTK should let GDK position menus
Getting involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 10

In this last week, the master branch of GTK+ has seen 16 commits, with 2500 lines added and 2092 lines removed.

Planning and status
  • Jonas Ådahl and William Hua are working on the feature branch that provides a new, declarative API for positioning popups and menus; you can read about it in the blog post that was published last Friday, as well as on bug 756579.
Notable changes
  • Matthias Clasen merged the patches, written by Philip Withnall, that implement a structured logging API in GLib. This work is still ongoing.
Bugs fixed
  • 768657 places-view: fix open action for locations without a mount or volume
  • 768659 gtk/gtkfilechoosernativeportal.c: Don’t use g_autoptr()
  • 768756 GtkFileChooserNativePortal uses incorrect response id
Getting involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 9

In this last week, the master branch of GTK+ has seen 26 commits, with 2416 lines added and 180 lines removed.

Planning and status
  • Emmanuele Bassi is working on his GSK rendering branch, and Alex Larsson gave an initial review. Emmanuele also wrote a blog post on his GSK work.
  • The discussion on the release strategy is still going on on gtk-devel-list; opinions are still welcome.
  • William Hua has been rebasing his branch on the new, Wayland and Mir ready popup positioning API, which replaces positioning via global coordinates.
Notable changes
  • Matthias Clasen landed the “portals” implementation for negotiating access to resources outside of a sandbox in both GLib and GTK+. You can read more about it on his blog.
Bugs fixed
  • 768485 Change the priority of the window-close idle to G_PRIORITY_DEFAULT
  • 768499 portal support for gtk+
  • 768546 Wrong documentation for the “move-viewport” signal of GtkTextView
Get Involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 8

In this last week, the master branch of GTK+ has seen 23 commits, with 1154 lines added and 121 lines removed.

Planning and Status
  • Matthias continued to work on the portal branches of GLib and GTK+.
  • Emmanuele continued to make gsk render widgets on the gsk-renderer branch.
  • Philip Withnall is working on a patch series to make GLib support structured logging to the systemd journal here.
Notable Changes
  • Carlos Garnacho improved compatibility of Wayland clipboard handling with legacy X clients.
  • Matthias made it possible to hide the preview button in print dialogs.
  • Eric Koegel added support for the Xfce session manager to GtkApplication
  • Georges Basile Stavracas Neto added support for background-blend-mode to the GTK+ CSS machinery.
  • Over in GLib, Matthias added a new gio utility that combines the functionality of the various gvfs commandline tools into one.
Bugs fixed
  • Bug 767965Improve heuristics to detect remote filesystems
  • Bug 768184headerbar: don’t throw a warning if title widget is hidden
  • Bug 768082 – Copying from Wayland to NEdit doesn’t work
  • Bug 768177 CLIPBOARD target request after PRIMARY request times out
  • Bug 768142 Incorrect order of $(LIBS) and $(OBJS) in Makefile.example caused “undefined reference”
  • Bug 693203GtkApplication does not support Xfce session manager
  • Bug 768305Gtk+ should support background-blend-mode
Get Involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

This Week in GTK+ – 7

In this last week, the master branch of GTK+ has seen 29 commits, with 4744 lines added and 4340 lines removed.

Planning and Status
  • GTK+ 3.21.3 was released
  • Matthias continued to work on the portal branches of GLib and GTK+.
  • William Hua is reworking the menu positioning API from bug 756579 following the hackfest discussion.
  • Emmanuele pushed a new revision of the gsk branch.
  • Carlos Soriano is working on a new pathbar implementation for the file chooser and nautilus.
Notable changes
  • Emmanuele fixed some fallout in firefox from the GdkDrawingContext introduction.
  • Ray Strode cleaned up some headerbar code and added support for expanding children
  • Matthias fixed a crash in GtkColorChooser and another one in GtkInspector
Bugs fixed
  • Bug 767851 – popover arrows broken in some orientations
  • Bug 767849 – crash in focus handling
  • Bug 724332 – GtkHeaderBar need to support an expand property
  • Bug 768025 – entry.warning & entry.error broken
Get Involved

Interested in working on GTK+? Look at the list of bugs for newcomers and join the IRC channel #gtk+ on irc.gnome.org.

Adwaita

Today, Jakub Steiner from the GNOME design team is going to talk about Adwaita, the default theme for GTK+; the tools that the designers can use to style GTK+; and how the toolkit changed to allow a better design workflow.

Adwaita is the user facing façade of GTK+. In the past GTK+ had no face; there was no properly defined look for the toolkit. Like many things in the FOSS world, it was a bring your own. There was Raleigh, a fallback skin that only showed up if something went sideways with theming or the system settings. And you didn’t really want to see that.

Adwaita

CSS

With GTK+ 3.0 a bold new effort has started. An effort to put visual designers in charge of visual design, using tools they understand. Instead of resorting to theme engines to draw unique controls, a styling engine used on the web has been chosen. The “everything is a box” CSS model applied to GTK+ rather well. It took a lot of effort, mainly on the shoulders of Benjamin Otte, who over the years managed to give us what we dreamed of: a CSS-like box model, allowing us to space elements/controls using padding, margins, borders and nifty features like minimum width. On the selector side, we aren’t dealing with the direct nested widget structure that changes from release to release, but we were given an abstracted, HTML-like DOM structure, with nodes and classes. Nodes are also consistently carrying state and are easier to animate.

SCSS

In GTK+ there are a lot of controls that look like a button but aren’t a button. Every programmer is on the lazy side, and that’s a good thing. Designers aren’t any different. It’s so positive that there is an acronym for it, DRY — don’t repeat yourself. So in the old Adwaita, when we designed the look of some things that all looked the same, we only had one block of properties and a ton of selectors — the targets of that look. Buttons, dropdowns, you name it. Not much typing, but insanity to alter.

SASS came to the rescue by providing means to define a common drawing procedure once, but reuse it in a well structured stylesheet. You would be able to draw things “like a button” but not define it as a button. You would still find a dropdown nicely semantically organized in a dropdown section. SASS calls these macros mixins and you will find our drawing ones in src/gtk/theme/Adwaita/_drawing.scss.

/* Switch Slider being a button */
slider {
/* ... */
@include button(normal, $edge: $shadow_color);
}
Inspector

A massive improvement for the designer’s workflow has been the introduction of the Inspector. The inspector is an invaluable tool to test out new style interactively or to figure out why a particular selector isn’t working. There are a couple of powerful tools it provides:

  • Widget selector. You can interactively point at a widget to learn about its properties or where it lives in the widget tree stack. Since 3.20 you can also learn about its CSS nodes, learn what sort of states it can get to, learn all the classes it has been assigned. It can also tell you where in the stylesheet the set property has been defined. This helps you figure out why your selector isn’t working. Somewhat. It would be real nice to see all matching selectors, even those that have been overriden by those that take precedence.
  • Interactive CSS stylesheet. You can write a CSS rule and have it applied in real time. This is not only useful to figure out a proper selector, but also experiment with drawing using GTK+ directly rather than using tools like Inkscape. Being able to iterate fast and try out things results in better design.

If this all sounds very similar to what modern browsers provide, it’s not much of a coincidence.

CSS Nodes in the Inspector
CSS Nodes in the Inspector
Future Improvements

A major factor that’s making us less flexible in terms of being able to alter Adwaita are the graphic assets. There are still a couple of things that we have to resort to using image assets for. Those are actually in a large asset sheet SVG and we have a bunch of scripts to chop up multiple sized images (for HiDPI). It remains a hassle to add or change a particular bit.

To make this a little less boring, here’s a little web demo of how we could possibly avoid using image assets to draw GtkScale sliders and use simple CSS boxes instead:

<div id="scale" class="scale">
  <div class="trough"></div>
  <div id="slider" class="slider run-animation"></div>
</div>

<style type="text/css">
.scale {
  position: relative;
  width: 100%;
  height: 64px;
}
.scale:hover { }
.trough {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  height: 8px;
  border-style: solid;
  border-width: 2px;
  border-radius: 4px;
  left: 0; right: 0;
  border-color: #a7a7a7;
  background-color: #b1b3b1;
  background-image: linear-gradient(to bottom, #a7a7a7, #bebebe);
  box-shadow: 0 1px 0 rgba(255,255,255,0.8);
}
.slider {
  position: absolute;
  width: 48px; height: 48px;
  top: 50%;
  left: 0%;
  transform: translateY(-50%) translateX(0%) rotate(0deg);
  border-style: solid;
  border-width: 2px;
  border-color: #a7a7a7;
  border-radius: 0;
  background-color: #e0e0e0;
  background-image: linear-gradient(135deg, #ededed, #d3d3d3);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.2),
              2px 2px 2px rgba(0,0,0,0.1);
}
.slider.run-animation {
  animation-name: morph, progress;
  animation-delay: 6s,10s;
  animation-duration: 3s,3s;
  animation-iteration-count:1,infinite;
  animation-direction: normal, alternate;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
}
.slider.run-animation:hover {
  /* the best way to reset CSS animations is switching between identical keyframes */
  animation-name: morphClone, progressClone;
}
@keyframes morph {
  0% {
    border-radius: 0;
    transform: translateY(-50%) translateX(0%) rotate(0deg);
  }
  90% {
    border-radius: 50% 50% 0 50%;
    transform: translateY(-50%) translateX(0%) rotate(0deg);
  }
  100% {
    border-radius: 50% 50% 0 50%;
    transform: translateY(-60%) translateX(0%) rotate(45deg);
  }
}
@keyframes morphClone {
  0% {
    border-radius: 0;
    transform: translateY(-50%) translateX(0%) rotate(0deg);
  }
  90% {
    border-radius: 50% 50% 0 50%;
    transform: translateY(-50%) translateX(0%) rotate(0deg);
  }
  100% {
    border-radius: 50% 50% 0 50%;
    transform: translateY(-60%) translateX(0%) rotate(45deg);
  }
}
@keyframes progress {
  0% {
    left: 0%;
    transform: translateY(-60%) translateX(0%) rotate(45deg);
  }
  100% {
    left: 100%;
    transform: translateY(-60%) translateX(-100%) rotate(45deg);
  }
}
@keyframes progressClone {
  0% {
    left: 0%;
    transform: translateY(-60%) translateX(0%) rotate(45deg);
  }
  100% {
    left: 100%;
    transform: translateY(-60%) translateX(-100%) rotate(45deg);
  }
}
</style>

Essentially the slider is a box with 3 corners rounded and rotated by 45 degrees. All we need is boxes.

    /* transforms-based scale slider on the web */
.slider {
  position: absolute;
  width: 48px; height: 48px;
  top: 50%;
  left: 0%;
  /* move up slightly after rotation, thus not 50% */
  transform: translateY(-60%) rotate(45deg);
  border-style: solid;
  border-width: 2px;
  border-color: #a7a7a7;
  border-radius: 50% 50% 0 50%;
  background-color: #e0e0e0;
  background-image: linear-gradient(135deg, #ededed, #d3d3d3);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.2),
              2px 2px 2px rgba(0,0,0,0.1);
}