Author: AlexZhang
Based on discussions from April 16th to 20th and merged PRs within the week.
This week was a productive one, with the Makepad team making progress on multiple fronts, including platform features, core widget fixes and improvements, performance optimizations, and adjustments to the underlying rendering architecture.
Key advancements include resolving gesture interaction challenges on iOS, fixing a critical bug in Dock state loading, and advancing Android XR support. Concurrently, the team continues performance analysis and optimization (text, font stack) and addresses various widget and platform-related issues. Planning for CI also signals future improvements to the development workflow. Some known minor issues (like PortalList warnings and Html link parsing) have been identified and are awaiting further action.
iOS Long Press Gesture Support (#715):
UIGestureRecognizer
"takes over" the event stream upon recognizing a gesture, preventing the underlying view (Makepad's MTKView) from receiving subsequent touch events (like FingerUp
) until the gesture fully ends (finger lifted). This made it difficult to trigger Makepad's internal events while the gesture was ongoing (finger held down but long press duration met).cancelsTouchesInView
property to false
, allowing the underlying view to continue receiving touch events even after the gesture is recognized.Android XR Support Advancement (Rik):
Window Management Improvements (#693):
Build and Platform Fixes:
Dock State Loading Bug Fix (#711):
LiveId
collisions in a new application instance. This happened because the unique LiveId
counter resets in the new instance, potentially generating IDs that clash with unique IDs saved from the previous instance (used for dynamically created Splitters or Tabs), leading to the overwriting of the old layout.LiveId
s into new, string-based LiveId
s during the load_state
process, thus avoiding collisions. Kevin requested Rik to review this approach.PortalList / DrawList Issues:
smooth_scroll_to_end
function was improved to internally call smooth_scroll_to
(#691).DrawListId
index generation when using different templates for the same item_id
in a PortalList
. While it doesn't seem to break functionality currently, the team discussed debugging methods (panic, #[track_caller]
) to trace the source.Button State Bug Fix (#718):
CommandTextInput Improvements:
Html Widget Link Parsing Issue (Kevin):
<Html>
widget does not correctly parse and render link content (<a>
tag text) when the link tag is nested within other tags (like <code>
) that use custom subwidgets. The preliminary assessment points to the <Html>
widget's handling of subwidget content rather than an issue with the underlying HTML parser.cargo makepad check all
on all platforms.Makepad's event system (e.g., the Hit
enum) uses terms like FingerDown
, FingerUp
, FingerHoverIn
to describe touch and mouse interactions.
Discussion Point:
Rik mentioned the potential need to consider non-human users (like AI or "tentacled alien overlords" - humorously put) interacting with the UI in the future. In such scenarios, the term "finger" might become inappropriate. Rik noted that the W3C (World Wide Web Consortium) uses the more generic term "pointer" to encompass various input methods like mouse, touch, and pen, considering it a more robust approach.
Conclusion (Inferred):
While no immediate change was decided upon, the discussion indicates the team recognizes the limitations of "finger" and acknowledges the value of "pointer" as a more universal and future-proof term. This might suggest a future migration of Makepad's event system towards "pointer" events to better accommodate diverse input and interaction methods.
NIH syndrome refers to a cultural or organizational phenomenon where developers or organizations tend to avoid using, trusting, or buying existing products, research, standards, or knowledge from external (third-party) sources, even if they are readily available and potentially superior solutions. Instead, they prefer to redevelop or "reinvent the wheel" themselves.
Manifestation in the Discussion:
Kevin encountered difficulties with iOS gesture recognizers due to the complex and somewhat "overbearing" behavior of Apple's UIGestureRecognizer
(blocking event propagation to underlying views). He worried they might need to implement a gesture recognizer from scratch to gain the necessary control.
Rik expressed concern about the necessity of implementing low-level features ("the hard cost of NIH") but also emphasized a key advantage of Makepad: if the existing solution (Apple's) doesn't meet their needs, they can choose to implement it themselves ("atleast we CAN choose", "cherish the thought that we CAN"). He contrasted this with web development, where developers are often limited by browser APIs and cannot modify underlying behavior ("on web you cant choose").
Kevin acknowledged his own NIH tendencies ("I too suffer from NIH syndrome"), having previously developed his own operating system. However, he felt that a relatively high-level feature like gesture recognition shouldn't fall into the category of things needing reinvention, implying Apple should provide better APIs or customization options.
This discussion reflects the common dilemma developers face when dealing with limitations of external platforms or libraries:
Makepad's Stance (Inferred):
The discussion suggests the Makepad team prefers leveraging platform features when possible but retains the ability to customize or even reimplement low-level components when necessary to ensure the final user experience and framework flexibility. They recognize the cost of NIH but also value the freedom to "choose to build it themselves" as an advantage.
In summary, NIH syndrome describes a "not-invented-here" mentality. The Makepad team's discussion shows an awareness of this pitfall while also valuing the freedom to develop necessary components independently when required.
Apple's UIGestureRecognizer
is a powerful framework for identifying various user gestures on touchscreens, such as Tap, Long Press, Pan, Pinch, Rotation, and Swipe.
Its core idea involves:
UIView
.UITouch
objects containing start, move, end, cancel info) received by the view they are attached to and its subviews.Possible
: Initial state.Began
: Gesture has started (e.g., long press held long enough, pan moved far enough).Changed
: Gesture is ongoing and changing (e.g., finger panning or pinching).Ended
/ Recognized
: Gesture completed successfully (e.g., finger lifted after a tap or pan).Cancelled
: Gesture cancelled by the system or another recognizer.Failed
: Touch sequence didn't match the gesture requirements."Taking Over" the Event Stream (Default Behavior)
The key behavior mentioned in the discussion is that UIGestureRecognizer
defaults to "taking over" the event stream:
touchesBegan:
, touchesMoved:
, touchesEnded:
methods).Began
or Recognized
/Ended
), by default, it prevents subsequent raw touch events from being delivered to that view and its subviews. This is what Kevin referred to as "take over the event flow and do not allow the underlying view to receive future events".The Role of the cancelsTouchesInView
Property
The cancelsTouchesInView
property, which Kevin later found, is key to resolving this:
cancelsTouchesInView = true
(Default): When the gesture is recognized, all ongoing touch events are marked as cancelled (sending touchesCancelled:
to the view), and subsequent touch events are not delivered to the view until the gesture ends. This was the cause of Makepad's underlying view not receiving FingerUp
events.cancelsTouchesInView = false
: When the gesture is recognized, touch events continue to be delivered to the view. This means the view's touchesBegan:
, touchesMoved:
, touchesEnded:
methods will still be called, even while the gesture recognizer is also processing the touches.Why cancelsTouchesInView = false
is Important for Makepad
Makepad has its own event handling system that requires the complete sequence of touch events (down, move, up) to drive its internal Hit
detection and widget event dispatch logic. If the iOS gesture recognizer intercepts touchesEnded
after recognizing a gesture (like a long press), Makepad wouldn't know when the finger was lifted, couldn't trigger the corresponding FingerUp
event, and could end up with inconsistent UI states or broken interactions.
By setting cancelsTouchesInView = false
, Kevin allowed Makepad's underlying view (MTKView
) to continue receiving raw touch events (including the finger lift event) even after an iOS long press gesture was recognized. This enables Makepad to correctly generate and process its internal FingerUp
event.
Apple's UIGestureRecognizer
is a powerful state machine for complex gestures. Its default behavior intercepts raw touch events from the view upon recognition to simplify interaction logic. However, for frameworks like Makepad with their own complete event systems, this default is disruptive. Setting cancelsTouchesInView = false
allows raw touch events to continue flowing to the underlying view, enabling Makepad to receive and process the full user interaction sequence.