Is ui::Button supposed to work stand-alone?

When I try, onDragDrop never fires because in State::handleButton the clickedWidget seems to be someone besides my button. clickedWidget seems to be a PN4rack6widget6WidgetE (according to std::string s = typeid(clickedWidget).name():wink:

I’m not sure what you’re asking, but you should simply override the onAction() event for button clicks.

Sorry, that was missing context. So, yes, I have a button that derives from Button, and overrides onAction(). then I do OpaqueWidget::addChild(Button*). When I click the mouse on the button, it responds visually, but onAction never fires.

Why not? because Button::onDragDrop() is never called.

Why not? because that code in State::handleButton that I mentioned in the original post. I don’t understand that code, but it looks like it’s about the button sitting in some container. When I search in Rack I don’t see Button standing alone, so I figured maybe it doesn’t want to.

onDragEnd does got called, as to most of the others.

What you’re describing should work because your Button subclass should consume the DragHover event, not its parent. Does it override any other events?

Here’s the source for my button:

class Button2 : public Button
    // this isn't firing. don't know why
    void onAction(const ::rack::event::Action& e) override {
        DEBUG("onAction from button");

    void onDragEnd(const ::rack::event::DragEnd& e) override {
        DEBUG("on DRAG END FOR ME handler = %d", bool(handler));
#if 0
        // this is my work-around for now
        if (handler) {
            DEBUG("calling handler (ourter dismisser");
            auto tempHandler = handler;
            handler = nullptr;                  // only call it onece


    ~Button2() {
        DEBUG("dtor of button");

    std::function<void()> handler = nullptr;

Here’s the output: on DRAG END FOR ME handler = 1

Oops, didn’t hit reply before.