Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MX Master 3 Thumbwheel: Very inconsistent if Interval set above 1 #231

Open
gdiShun opened this issue Apr 12, 2021 · 9 comments
Open

MX Master 3 Thumbwheel: Very inconsistent if Interval set above 1 #231

gdiShun opened this issue Apr 12, 2021 · 9 comments

Comments

@gdiShun
Copy link

gdiShun commented Apr 12, 2021

Basically, Interval: 1 is way too fast for me. So I've tried setting it to 2 or 3, but both result in behavior that's way too inconsistent and unpredictable. The easiest way to illustrate this is setting it to those values, then simply scrolling from bottom-to-top as fast as you can. And then, do the same thing as slow as you can. For me, I use it for volume, I can go from 0% to 80+% in that one fast scroll, but the slow scroll won't move the volume at all. Despite traveling the same distance, the scroll wheel registers extremely different values.

I was able to fix this in a hacky way by setting Interval to 1, and then changing Thumbwheel.cpp from this:

            if(direction > 0)
                scroll_action = _config.rightAction();
            else
                scroll_action = _config.leftAction();

to this:

            if(direction > 0) {
            	count += direction;       	
	        if(count > 3) {
               		scroll_action = _config.rightAction();
			count = 0;
		}
            }
            else {
            	count += direction;
	        if(count < -3) {
	                scroll_action = _config.leftAction();
		        count = 0;
		}
            }     

I imagine there's a better, less hacky, and more user-friendly way of solving it however.

@dhitchcock
Copy link

I doubled down on your hack. I take no pride in this, it's amateur stack over flow copy-pasta I added to your idea, but damn if my quality of life hasn't improved with it! I just kinda reset the counter when you switch directions or start a new spin to keep the behavior consistent.

outside _handleEvent method
#include <chrono>
using namespace std::chrono;

int8_t count = 0;
milliseconds last_thumb_scroll_event = duration_cast< milliseconds >(
    system_clock::now().time_since_epoch()
);
inside _handleEvent method
            milliseconds this_event = duration_cast< milliseconds >(
                system_clock::now().time_since_epoch()
            );

            auto since_last_event = std::chrono::duration_cast<std::chrono::milliseconds>(this_event - last_thumb_scroll_event);

            if(since_last_event.count() > 250) {
                count = 0;
            }

            last_thumb_scroll_event = this_event;

            if(direction > 0) {
                if (count < 0) {
                    count = 1;
                }
                else {
                    count += direction;
                    if(count > 5) {
                        scroll_action = _config.rightAction();
                        count = 0;
                    }
                }
            }
            else {
                if (count > 0) {
                    count = -1;
                }
                else {
                    count += direction;
                    if(count < -5) {
                        scroll_action = _config.leftAction();
                        count = 0;
                    }
                }
            }

I too plead for someone to do a better job of this, but I'm content for the meantime!

@yawor
Copy link

yawor commented Apr 22, 2021

I've tried mapping Left/Right gestures with thumb button on MX Master 2S to workspace switching in Gnome 40:

                { direction: "Right"; mode: "OnInterval"; interval: 10; action: { type: "Keypress"; keys: ["KEY_LEFTMETA", "KEY_LEFTALT", "KEY_RIGHT"]; }; },
                { direction: "Left"; mode: "OnInterval"; interval: 10; action: { type: "Keypress"; keys: ["KEY_LEFTMETA", "KEY_LEFTALT", "KEY_LEFT"]; }; },

It works ok as long as I only have two workspaces, which is problematic because Gnome creates workspaces dynamically to always have another empty one. If I have more than two, then it's really hard to switch to specific one as it goes straight to first or last.
I think the main issue is that the interval doesn't really work as interval. It behaves more like a dead zone. If I set it to 10, I need to first move 10 pixels to start the first event, but after that it doesn't wait for another 10 pixels, but fires more events every 1 px instead. The interval counter should reset after each event.

@meugr
Copy link

meugr commented May 3, 2021

@yawor is right. Now it's works poor.
I try to bind to thumbwheel Alt+Tab and Alt+Shift+Tab, But it is impossible to work with it

@dszmaj
Copy link

dszmaj commented May 22, 2021

@dhitchcock I've used your hack to do what @yawor is trying to do and it works perfectly! Now I can comfortably switch between as many workspaces as I need.

Great job! Super useful!

my config:


devices: ({
  name: "Wireless Mouse MX Master 3";

  smartshift: { on: true; threshold: 10; };

  hiresscroll: {
    hires: true;
    invert: false;
    target: false;
  };
thumbwheel:
{
    divert: true;
    invert: false;
    right:
    {
        interval: 3;
        direction: "Left";
        mode: "OnInterval";
        action =
        {
            type: "Keypress";
            keys: ["KEY_LEFTCTRL", "KEY_LEFTALT", "KEY_DOWN"];
        };
    };
    left:
    {
        interval: 3;
        direction: "Right";
        mode: "OnInterval";
        action =
        {
            type: "Keypress";
            keys: ["KEY_LEFTCTRL", "KEY_LEFTALT", "KEY_UP"];
        };
    };
};

  // 4000 max for MX Master 3.
  dpi: 1800;

  buttons: (

    // Thumb button.
    { cid: 0xc3; action = { type: "Keypress"; keys: ["KEY_LEFTCTRL", "KEY_W"]; }; },
    // Top button.
    { cid: 0xc4; action = { type: "ToggleSmartshift"; }; }

  );
});

@gfduszynski
Copy link

gfduszynski commented Aug 16, 2021

I've give it a shot and as far as I can tell the best fix for me is just commenting out (ThumbWheel.cpp:152)

            if(scroll_action) {
                //scroll_action->press(true);
                scroll_action->move(direction * event.rotation);
            }

press(true) resets the accumulator for axis in IntervalGesture.cpp.
Reset should only occur at the end of the movement, not during as is now.
Works good for me :)

@zyoungdev
Copy link

gfduszynki's fix did not work for me on arch linux with MX Master 3. When using an interval greater than 1, the event fires randomly and when it does fire, it runs the action multiple times. An interval of 1 is too sensitive to be useful.

@gfduszynski
Copy link

@zyoungdev Can you share your config for thumbwheel ? Mine is as follows:

    thumbwheel:
    {
        divert: true;
        invert: false;
        left:
        {
            threshold: 1;
            interval: 10;
            direction: "Right";
            mode: "OnInterval";
            action = { type: "Keypress"; keys: ["KEY_LEFTCTRL", "KEY_PAGEUP"]; };
        };
        right:
        {
            threshold: 1;
            interval: 10;
            direction: "Left";
            mode: "OnInterval";
            action = { type: "Keypress"; keys: ["KEY_LEFTCTRL", "KEY_PAGEDOWN"]; };
        };
    };

Also, the last commit I have is: 6bb4700

@gfduszynski
Copy link

gfduszynski commented Oct 17, 2021

As my previous explanation was not clear I'll try to do a better job. (@iFwu)
Call to scroll_action->press(true); with pretty much any gesture handler resets the state.

Relevant code from IntervalGesture.cpp

void IntervalGesture::press(bool init_threshold)
{
    _axis = init_threshold ? _config.threshold() : 0;
    _interval_pass_count = 0;
}

ThumbWheel.cpp:152 event handler for event.rotation triggers press for every movement of the wheel.
This makes the config unusable.

By the way I'm still running logiops with commented out //scroll_action->press(true); and it works fine.
However once I've got it working it turned out to not be such useful as I initially thought.

@zyoungdev
Copy link

My mistake! I compiled it incorrectly**. After compiling with the change from gfduszynski's fix above, I was able to utilize the threshold value for the thumbwheel. Here is my thumbwheel config:

// other config...
  thumbwheel: {
    divert: true;
    left: {
      mode: "OnInterval";
      interval: 15;
      action = { type: "Keypress"; keys: ["KEY_LEFTCTRL", "KEY_TAB"]; };
    };
    right: {
      mode: "OnInterval";
      interval: 15;
      action = { type: "Keypress"; keys: ["KEY_LEFTCTRL", "KEY_LEFTSHIFT", "KEY_TAB"]; };
    };
  };
// other config...

** I compiled using the AUR package but forgot to use -e flag on makepkg to make the changes persist.

Ety60 added a commit to Ety60/logiops-interval-fixed that referenced this issue Jul 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants