Bypass Rack Windows Alt's behaviour on a specific module rect?

On Windows (but I suppose also on Mac and Linux), holding Alt button and drag with Mouse (Left button), by default it moves the whole Window.

I’d like to bypass this behaviour if I hold Alt and drag with Mouse (Left button) on a specific Rect of my module plot (easily defined by nvgRect(args.vg, x, y, w, h)).

Is it that possible?

Thanks for any tips

If this is Rack behavior, rather than Windows, then yes, you can do your own handling.

Yes, it’s easy to do. I did it in my ancient Seq++. Make sure you really want to do it, however. I found it rather difficult to get used to, at least for my application. One of the reasons I ended up putting in a key re-mapping feature.

Should I watch it here? SquinkyVCV-main/src/Sequencer4Module.cpp at master · squinkylabs/SquinkyVCV-main · GitHub

At first watch, can’t see any “alt” bypass control on there, but maybe because I was looking faster…

I think it intercepts control key sequences. It’s in some other class, I’ll look later today and get a better pointer for you.

It’s in here. Look for the word “hover”

1 Like

Thanks for your time and support. Not sure I got it correctly anyway:

void onHoverKey(const event::HoverKey &e) override {
    bool isAlt = (e.mods & RACK_MOD_MASK) == GLFW_MOD_ALT;
    if (isAlt) {
        e.consume(this);
    } else {
        OpaqueWidget::onHoverKey(e);
    }
}

This way, pressing “alt” within the plot and than leftclick mouse button to “drag” an element in the plot, should avoid Rack on move the window, but it still moves it around…

Am I missing somethings other? Maybe onDragStart/Move etc?

I’m not sure, it’s been so long since I’ve looked at that. Seq++ was written for rack version 0.6! But I think that may be all you need to do. It’s also been a while since I’ve dragged things. So…. ?

1 Like

I see. No prob: thanks for the effort you give to me.

Since 0.6, seems lots is changed. Looking at the 1.0 source, seems that now this behaviour is on ScrollWidget::onHoverScroll?

Tried to override it, but still can’t get it working:

void onHoverScroll(const HoverScrollEvent &e) override {
    int mods = APP->window->getMods();
    bool isAlt = (mods & RACK_MOD_MASK) == GLFW_MOD_ALT;
    if (isAlt) {
        e.consume(this);
        return;
    } else {
        Plot::onHoverScroll(e);
    }
}

Shouldn’t this work? Stil it drags… :frowning:

The same using this code:

void onHoverScroll(const HoverScrollEvent &e) override {
    int mods = APP->window->getMods();
    bool isAlt = (mods & RACK_MOD_MASK) == GLFW_MOD_ALT;
    if (isAlt) {
        e.consume(this);
    }

    if (e.isConsumed()) {
        return;
    }

    Plot::onHoverScroll(e);
}

Which try to equals (more or less) RackScrollWidget intercepting CTRL… but none!

That code is from a module in the VCV 2 library. It works with current vcv.

I see. So there should be somethings more, since that exact code won’t bypass main/rack ALT behaviour…

seems strange, if that code bypasses racks ctrl behavior and other behaviors. But I haven’t tried it in a long time - for all I know it doesn’t work any more. I’d try normal debugging techniques, but don’t really have any more to tell you.

Update: just tried it with the version in the library. control keys work fine. If you don’t want to figure it out yourself, you could build that module and try modifying it for alt key…

I could :slight_smile: I’m not able to emulate the behaviour though: what should I do? Is the CTRL (i.e. bypass rack zoom) that is handled differently right? Can’t make it works on the Seq++… sequencer?

Ok, enabled the debugger and watched what’s going on on Rack engine. Basically, when press ALT, it falls inside here: Rack/src/ui/ScrollWidget.cpp at 8c6f41b778b4bf8860b89b36d5503fd37924077f · VCVRack/Rack · GitHub

Not on “onHover” method. So I see it always itercept that line before my onButton method.

This way, it seems that probably its not feasible? :frowning: Not sure I can place myself “before” the onButton method.

This comment // Handle Alt-click before children, since most widgets consume Alt-click without needing to. and that return make me think won’t be possible…

Interesting. I guess if you could somehow get that on button first, but you would probably have to make some widget be a child or rack itself. Don’t know if that’s possible or not. Maybe someone else will…

Its clearly become useless also GLFW_MOD_ALT if in fact we cant use it…

nothing to do, I’m not able to intercept the action before Rack windows, damn!

your suggestion is about… adding a parent of Rack GUI? Wouldn’t this be devastating? :smiley: Can’t imagine how many situations need to be handled…

I think the great @stoermelder already explore this context: vcvrack-packone/src/Stroke.cpp at v2 · stoermelder/vcvrack-packone · GitHub

Let me investigate, probably he does what you suggest @Squinky , add the Widget on top level of Rack :slight_smile:

EDIT: added my widget this way:

APP->scene->rack->addChild(new Test());

But of course can’t “see” it size pos/size I think are absolute:

struct Test : Widget {
	Test() {
		box.size = Vec(100, 30);
		box.pos = Vec(25, 280);
	}

	void draw(const DrawArgs &args) override {
		nvgBeginPath(args.vg);
		nvgRect(args.vg, 0, 0, box.size.x, box.size.y);
		nvgFillColor(args.vg, nvgRGBA(255, 0, 0, 255));
		nvgFill(args.vg);
		nvgClosePath(args.vg);
	}

	void onHoverKey(const HoverKeyEvent &e) override {
		DEBUG("onHoverKey");
		int mods = e.mods;
		bool isAlt = (mods & RACK_MOD_MASK) == GLFW_MOD_ALT;
		if (isAlt) {
			DEBUG("onHoverKey ALT %d", e.key);
		}

		Widget::onHoverKey(e);
	}
};

pressing a button, it doesn’t trigger onHoverKey :thinking: probably because I’m not hovering somethings since there is no relative pos?

If instead I do:

addChild(new Test());

onHoverKey is being triggered, so I think I miss somethings :slight_smile:

UPDATE: magically, if I remove these:

box.size = Vec(100, 30);
box.pos = Vec(25, 280);

I’m able to intercept the onHoverKey() now :thinking:

Honestly make no sense to me (no size/pos mean no pos/dimension, so no way to have a real layer on the stack).

But in fact it works this way? Mmmm…

I fear neither this will work. Tried to do this (so appending a widget to rack on top, follow @stoermelder trick on Stroke):

APP->scene->rack->addChild(new Test());

But it still call ScrollWidget widgets methods first (so its onButton(), which will consume and return). Using addChildBottom instead seems the same (it intercepts always ScrollWidget first).