Callbacks and captures

button->on_activate
    ([main_window=x::make_weak_capture(main_window)]
     (ONLY IN_THREAD,
      const x::w::callback_trigger_t &trigger, const auto &ignore)
     {
          auto got=main_window.get();
          if (!got)
              return; // Did not recover a strong reference.

          auto &[main_window]=*got;

          // ... main_window is ready for use.
     });

As explained in the section called “Special rules for captured references in callbacks”, callbacks attached to widgets can't capture references to parent or child widgets. This creates an internal circular reference that prevents the widgets, which are reference-counted objects, from getting destroyed.

But the application's action in response to a click on a lowly button typically involves doing work that often affects the entire application and the entire display window.

One solution is to use x::make_weak_capture(), from the core LibCXX library, to capture one or more weak pointers. The callback attempts to get() a regular reference from it, and proceeds with its business if this succeeds. If the callback happens to execute while the main window is getting destroyed, and the top level main_window no longer exists, get() fails to recover the strong references, and the callback bails out, and lets the execution thread finish cleaning things up.

In gridlayoutmanager.C each button's on_activate() takes this approach. Strictly speaking, gridlayoutmanager.C doesn't actually need to do this. Each button's action affects only other widgets that are neither its parent or child widget; gridlayoutmanager.C uses weak captures only to give an example of using this design pattern.