Monday, November 29, 2021

Brabantia BBEK1114 Break Maker

The manual for this bread maker is not very good and the functionality is limited. If I were buying another, I would look for something that lets me start at any point in the programs instead of only being able to start at the beginning.

I mostly used the Sweet Bread and French Bread programs. Timing isn't in the manual, which makes it difficult to add nuts, etc. as the bell is not very loud: unless you are right by the machine and listening for it, it is easy to miss.

The timer counts down. If you add time (up to 15 hours total) the additional time is added at the beginning, doing nothing. The program itself is not changed otherwise. This is a problem because all the ingredients are in the machine and the yeast can start fermenting. It would be better to do an initial mix and beat down the dough periodically, instead of leaving it to sit un-mixed. But there is no such option. Best one can do is leave it in a cool place so the dough doesn't rise too much and overflow. 

There is no indication in the manual of the baking temperature. I haven't tried to measure it.

I generally use only a teaspoon or less of dry yeast and about half the indicated sugar in the 750g recipe and it rises to fill the machine, sometimes rising to press against the top. I haven't tried a 1kg recipe but expect it would overflow if I didn't do anything to limit its rising.

I have only made a few of the recipes. The results are surprisingly good and it is very easy, but more like cake than bread. Quite short and crumby. Adding some gluten to the 11.5% protein flour helps a bit.

Sweet Bread

  • 3:45 - Start / Mix
  • 3:41 - Knead
  • 3:38 - Rest
  • 3:30 - Knead
  • 3:20 - Rest
  • 3:10 - Knead
  • 2:55 - Rest
  • 2:40 - Knead
  • 2:35 - Add / Knead
  • 2:25 - Ferment
  • 1:35 - Beat down
  • 1:34 - Ferment
  • 0:50 - Bake
  • 0:00 - Keep warm

French Bread

  • 4:00 - Start / Mix
  • 3:56 - Knead
  • 3:50 - Rest
  • 3:40 - Kenad
  • 3:35 - Rest
  • 3:30 - Knead
  • 3:10 - Rest
  • 2:55 - Knead
  • 2:50 - Add / Knead
  • 2:40 - Ferment
  • 1:40 - Beat down
  • 1:39 - Ferment
  • 0:50 - Bake
  • 0:00 - Keep warm

Monday, November 15, 2021

Libinput: using libinput as a library

The libinput documentation includes a section on using libinput as a library, but with no prior experience with libinput, I found it inadequate to get me oriented. So, here are some additional notes.

Background

libinput is a library to handle input devices in Wayland compositors and to provide a generic X.Org input driver. It provides device detection, device handling, input device event processing and abstraction so minimize the amount of custom input code compositors need to provide the common set of functionality that users expect. Essentially, it is an interface to the input devices.

libinput is not used directly by Wayland applications, it is an input stack used by the compositor.

libinput is not used directly by X applications but rather through the custom xf86-input-libinput driver.  

Libinput may be used by programs other than these display servers. For example, the libinput distribution provides several tools for testing and interacting with libinput. Any program that accesses the input devices supported by libinput may use libinput to access them, as an alternative to accessing them directly.

libinput is designed to handle all input devices available on a system but it is possible to limit which devices libinput has access to. For example, the use of xf86-input-libinput depends on xorg.conf snippets for specific devices. But libinput works best if it handles all input devices as this allows for smarter handling of features that affect multiple devices.

libinput handles all common devices used to interact with a desktop system. This includes mice, keyboards, touchscreens, touchpads and graphics tablets. libinput does not expose the device type to the caller, it solely provides capabilities and the attached features (see this blog post).

libinput does not handle some devices. The primary reason is that these device have no clear interaction with a desktop environment.

See Building against libinput for guidance on configuration and linking the libinput library. 

Libinput does not have many configuration options. This is deliberate.

Initializing a context

The first step in using libinput is initializing a context. The context is manifest as a data structure. Most calls to libinput functions require this context as an argument.

The libinput API documentation has a section on Initialization and manipulation of libinput contexts.

Saturday, November 13, 2021

Libinput sample

The libinput API documentation has a sample program on the main page but it doesn't compile as given.

This revision of it does compile and run:

#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <libinput.h>
#include <libudev.h>
#include <stdio.h>

#define ANSI_HIGHLIGHT    "\x1B[0;1;39m"
#define ANSI_RED    "\x1B[0;31m"
#define ANSI_GREEN    "\x1B[0;32m"
#define ANSI_YELLOW   "\x1B[0;33m"
#define ANSI_BLUE   "\x1B[0;34m"
#define ANSI_MAGENTA    "\x1B[0;35m"
#define ANSI_CYAN   "\x1B[0;36m"
#define ANSI_BRIGHT_RED   "\x1B[0;31;1m"
#define ANSI_BRIGHT_GREEN "\x1B[0;32;1m"
#define ANSI_BRIGHT_YELLOW  "\x1B[0;33;1m"
#define ANSI_BRIGHT_BLUE  "\x1B[0;34;1m"
#define ANSI_BRIGHT_MAGENTA "\x1B[0;35;1m"
#define ANSI_BRIGHT_CYAN  "\x1B[0;36;1m"
#define ANSI_NORMAL   "\x1B[0m"


static int open_restricted(const char *path, int flags, void *user_data)
{
        int fd = open(path, flags);
        return fd < 0 ? -errno : fd;
}
 
static void close_restricted(int fd, void *user_data)
{
        close(fd);
}
 
const static struct libinput_interface interface = {
        .open_restricted = open_restricted,
        .close_restricted = close_restricted,
};

static void
log_handler(struct libinput *li,
    enum libinput_log_priority priority,
    const char *format,
    va_list args)
{
  static int is_tty = -1;

  if (is_tty == -1)
    is_tty = isatty(STDOUT_FILENO);

  if (is_tty) {
    if (priority >= LIBINPUT_LOG_PRIORITY_ERROR)
      printf(ANSI_RED);
    else if (priority >= LIBINPUT_LOG_PRIORITY_INFO)
      printf(ANSI_HIGHLIGHT);
  }

  vprintf(format, args);

  if (is_tty && priority >= LIBINPUT_LOG_PRIORITY_INFO)
    printf(ANSI_NORMAL);
}
 
 
int main(void) {
  fprintf(stderr, "start main\n");
        struct libinput *li;
        struct libinput_event *event;

        struct udev *udev = udev_new();

        if (!udev) {
          fprintf(stderr, "Failed to initialize udev\n");
          return -1;
        }
 
        fprintf(stderr, "create libinput context for udev\n");
        li = libinput_udev_create_context(&interface, NULL, udev);
        if (!li) {
          fprintf(stderr, "Failed to create libinput context\n");
          return -1;
        }

        libinput_log_set_handler(li, log_handler);
        libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);

        if (libinput_udev_assign_seat(li, "seat0")) {
          fprintf(stderr, "Failed to assign seat\n");
          libinput_unref(li);
          li = NULL;
          udev_unref(udev);
          return -1;
        }

        libinput_dispatch(li);
 
        while ((event = libinput_get_event(li)) != NULL) {
 
                // handle the event here
                fprintf(stderr, "in the event loop\n");
 
                libinput_event_destroy(event);
                libinput_dispatch(li);
        }
 
        fprintf(stderr, "unreference libinput context\n");
        libinput_unref(li);
 
        return 0;
}

 

This can be compiled with:

$  gcc -o sample sample.c `pkg-config --cflags --libs libinput` -ludev

 

Tuesday, November 9, 2021

Libinput - alternate acceleration profile for touchpad

I don't like the libinput acceleration profile for my laptop touchpad.

I have Debian 11 (bullseye) on my laptop with xfce4 desktop. It defaults to libinput for the touchpad but I didn't like the acceleration profile. It was either too fast for accurate fine movements or too slow for traversing the display. While I could adjust the speed, I couldn't find any setting that was satisfying. I don't recall when the driver changed but it has been a long time now, maybe since I replace Mint with Debian a year or two ago. In any case, it is long enough that I am not merely suffering from a slight change to the acceleration profile conflicting with my muscle memory: even given plenty of time to adjust, I still don't like the libinput acceleration profile.

Recently, I decided to do something about it. I tried the Synaptics driver and it was better but still not what I wanted. I tried the evdev driver but it didn't work at all: the cursor didn't move no matter what I tried. No error message: just no movement. I really wanted to try some of the acceleration profiles that evdev provides but eventually I gave up.

It seems that the Synaptics and evdev drivers are deprecated and the libinput driver will predominate in the future, so I decided to focus on it. Others have criticized its acceleration profile, with sentiments like mine. The libinput FAQ includes:

Why is libinput’s pointer acceleration worse than synaptics/evdev

This is a known problem affecting some devices and/or use-case but the exact cause is still unknown. It may be a device-specific issue, it may be a bug in libinput’s acceleration code, it may be a disagreement about how pointer acceleration should feel. Unfortunately this is something that affected users need to investigate and analyze.

As I had tried all sorts of settings and given it lots of time to get used to it but was still bothered by it, I decided to try implementing an alternate acceleration profile. I am not hopeful that this will ever be accepted into libinput. For good reason, the developers need to keep it simple and robust with minimal support resources. Adding features adds support burden. But I only care about support for me and my one system, and it is, after all, free software.

It took me a couple of days to learn enough to get started but once I familiarized with the libinput code a bit, it turned out to be easy to implement an alternate acceleration profile with hard coded parameters: just one function to change. Adding configuration parameters is a bigger challenge for another day. But as I am recompiling libinput anyway, changing the parameters in the code isn't a problem, and I don't want to be changing them anyway, once I get them right.

I built libinput per Building. This gave me a local repository.

I created a new branch: wip/alternate_profile.

I modified src/filter-touchpad.c, which contains the 'adaptive' profile acceleration code. I created a new function, touchpad_accel_profile_constrained_linear, modeled after the original touchpad_accel_profile_linear (which is, in fact, not a linear transfer function) that implements the adaptive profile (the default profile) and changed the pointer to the transfer function to the new one. I don't yet know how to add the new profile selectable by configuration but I don't want to use the adaptive profile so replacing it is OK for now. It's a crude hack, but fixes my immediate problem and is a step towards adding a new profile.

The new profile has four hard-coded configuration parameters:

  const double minimum_factor = 0.05; /* unitless */
  const double maximum_factor = 0.75; /* unitless */
  const double lower_threshold = 15.0; /* mm/s */
  const double upper_threshold = 100.0; /* mm/s */

The acceleration factor is a simple function of speed:

   accel
   factor
     ^
     |       --------
     |      /
     |     /
     |----/
     +-------------> speed in


At speeds below lower_threshold, factor is minimum_factor.

At speeds above upper_threshold, factor is maximum_factor.

At speeds between the two thresholds, factor is a linear ramp from minimum_factor to maximum_factor.

This gives me precise control at slow speeds and a gradual transition to rapid movement at high speed. The transition is sufficiently smooth that it feels predictable. I may be wrong, but I think the linear ramp is fine: no need for any fancy curve, as long as the transition from slow to fast isn't too abrupt, i don't think the details of the curve matter. If it were a mouse, I might care about the details of the curve more, but a touchpad is so crude, it doesn't matter.

Otherwise, there are no 'magic' numbers, as there are in touchpad_accel_profile_linear, but there may be elsewhere. I haven't reviewed all the code of libinput, and much less so the Xorg libinput driver or Xorg server themselves.

The parameters are hard coded. There is no provision to set them by Xorg configuration files, xinput, xset or whatever. I don't yet know how to add such capability.

But it is easy enough to recompile and reinstall, so not too difficult to change the parameters.

Of course, installing this modified libinput affects the entire system and there is no provision for per-user configuration at this point. I am using it on my personal laptop, so there are no other users.

I am using this on an old Toshiba Satellite Pro C665. I also added a hwdb entry for it, as the default touchpad dimensions were incorrect. In  /etc/udev/hwdb.d/61-evdev-local.hwdb:

# Toshiba Sattelite Pro C665
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnTOSHIBA:*pnSatelliteProC665**
 EVDEV_ABS_00=1122:5863:58
 EVDEV_ABS_01=951:5118:99
 EVDEV_ABS_35=1122:5863:58
 EVDEV_ABS_36=951:5118:99

I followed the instructions at Coordinate ranges for absolute axes. I was surprised to find that hwdb only had entries for two Toshiba systems. You might check your own touchpad to make sure it is correct.

If you are interested, you can clone it from wip/alternate_profile

To build and try the new profile:

  1. $ git clone https://github.com/ig3/libinput.git
  2. $ cd libinput
  3. $ git checkout --track  origin/wip/alternate_profile
  4. $ meson --prefix=/usr builddir/
  5. $ ninja -C builddir/
  6. $ sudo ninja -C builddir/ install
  7. restart your X server (e.g. logout and login or reboot)

I have been using it for a few days now and it feels much more comfortable than the libinput 'adaptive' profile. I have good control at slow speeds and I can easily move the cursor across the screen. In summary, it works as I expected and I like it.

Linux touchpads in Xorg X Server with libinput

I have Debian 11 (bullseye) on my Toshiba Satellite Pro C665 laptop. It uses libinput by default but I found the cursor difficult to control. With a low acceleration I had precise control but it was tedious traversing the screen. With a high acceleration I could traverse the screen OK but precise control of the cursor was difficult to impossible. So, I began to learn far more than I ever wanted to know about Xorg X Server, libinput, synaptic, evdev and pointers in general. I have only learned a little: not yet enough to achieve reasonable behaviour.

My touchpad works with the libinput and synaptic input drivers but doesn't work with evdev. For reasons unknown, when I configure evdev there are no errors logged but the cursor doesn't move. The buttons are recognized but I can't move the cursor. Other's report this behaviour and the most common 'solution' is to use synaptic or libinput drivers. The events are generated. I have no idea why they are ignored when I try the evdev input driver. Maybe evdev is essentially unsupported software recent years and broke at some point and no one cares.

This thread addresses another fault in libinput but it includes instructions for re-building libinput from source. I have now done this both via 'apt build-dep' etc. as indicated there, and also from xf86-input-libinput which I built and installed with no ill effect.

The person who responded with the instructions for for building libinput said, among other things: "I agree that this isn't an ideal user experience. On the other hand, recompiling libinput in 2020 takes about as much time as taking out a credit card from your wallet and paying for another closed source macOS app." and there was some subsequent back and forth among respondents about how reasonable this workaround is.

I have been aware of X Server since the 1980's. I have been using Linux since the mid 90's, written device drivers from scratch, hacked parts of the kernel and built and debugged many packages through the years. I have been searching for a way to improve my touchpad behaviour for two days now and have learned only a little of what software is involved, how it all relates and how it is all configured. Had I not stumbled on the above linked thread, it might have been many more days before I learned how to build libinput from source and much longer to understand what all the code was doing to resolve that problem. I have looked at the code that implements the acceleration profile but it will be a long while before I understand how to add my own profile and configuration options (i.e. changes to processing of the Xorg configuration files, xinput, xset and who knows what other places might be required to make something that works).

The documentation (in all forms I can find, including man pages, tutorials and forum discussions) is typically terse, often using undefined terms and often inconsistent with the current implementation on my laptop. The software and how to configure it has obviously changed through the years and it is difficult to determine what advice applies to what version of the software. Even current Xorg documentation on the official Xorg website is inconsistent with my experience when using the libinput device driver.

My conclusions thus far:

The evdev device driver doesn't work: there are no errors but the cursor doesn't move when I use the touchpad. No idea why. Much of the documentation I can find about setting acceleration profiles seems to be specific to the evdev input device driver. I would like to try some of these profiles but I can't because the cursor doesn't move at all.

The synaptic device driver works but it is difficult to understand how to configure acceleration. Synaptics Pointer Acceleration makes some convincing arguments that the Synaptic driver is complex to the point of being unpredictable, though it might not be so intractable if one cares only about a single hardware configuration. The author is one of the main contributors to both the Synaptic and libinput device drivers, so well informed. After some effort I was unable to achieve what I wanted with this input driver.

The libinput driver is the default on my and many systems. Many complain about the acceleration. Documentation of it is misleading and there are very limited configuration options. I have been unable to configure it to allow my both fine control of the cursor and easy traversal of larger areas. The source code suggests (to my as-yet superficial understanding) that the implementation is more complex than and inconsistent with the documentation, with obscure heuristics determining the acceleration parameters, rather than configuration parameters.

It is a dismaying prospect to have to spend many more days if I want to understand what all the configuration options (across GUI configuration tools, command line tools and various configuration files for Xorg, udev, xfce4, etc., etc., etc.) are and what they do and which part(s) of the software they affect.

Presumably there is code in the hardware device driver, Xorg input driver and Xorg X Server that could and possibly do contribute to the overall mapping from the hardware to the cursor position. But it is a morass of poorly documented components, leading to confusion and every experiment thus far requires an hour or two of researching errors, installing and configuring tools, often to achieve little to nothing.

Labels