Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

DragToScroll - Universal Drag & Fling/Flick Scrolling


  • Please log in to reply
210 replies to this topic
DarKcyde
  • Guests
  • Last active:
  • Joined: --
LOL, I started reading the code. Strike #2, Ctrl to disable is already there.

cheek
  • Members
  • 71 posts
  • Last active: Jun 21 2014 03:24 AM
  • Joined: 01 Apr 2009

Exactly. Right now, if you click-hold, and don't move the mouse it still captures your right click. For example, Right-hold+Left click (like a rocker gesture) doesn't work. If there's no mouse movement, the right click should always happen.

I understand the motivation to allow normal right click behavior if you click and hold, but do not move the mouse.... I just don't understand how this would technically work, without interefering with other usage. I'm going to think more about how this might work, and followup with some changes and/or another post discussing this..

How about a quick-disable key? Like hold Ctrl to temporarily allow right-click dragging files in explorer.

Holding control and right clicking already does exactly that; try it out! ;)

Icon doesn't work in Win7 x64, using Autohotkey_L x64. I still have a Green H.

I was just reading something about this; it looks like there was a bug in the sample code used to embed and set the icons--it was already fixed elsewhere, I just wasn't paying attention. I haven't seen that behavior, but i'm on Win7x64 too, so I'll check out Ahk_L (haven't yet.) Try making the following change and let me know if that corrects the problem for you. In the CreateIconFromResourceEx dll call, you need to pass in the size of the icon data instead of 0.

Details here http://www.autohotke...p=207630#207630

hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData+22, UInt,0, Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData+22, UInt,nSize, Int,1, UInt,196608, Int,16, Int,16, UInt,0 )

This is wrong, nSize is not the correct size in bytes. It appears that NumGet is more correct, below.

There's also this conflicting information (from the original author), which says to use something different....
http://www.autohotke...p=387981#387981
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData+22, UInt,NumGet(IconData,14), Int,1, UInt,196608, Int,16, Int,16, UInt,0 )

This is probably unrelated to AHK_L. Will look more into this.



Per-application scroll selection would be nice. So you could specify Wheel-key for apps that need it, but use Wheel Message elsewhere.

As I mentioned above, This is something that's been on the adgenda for a while... It would certainly be a nice addition, and I'm sure I'll eventually write it in. However as of yet, I haven't had the time or impetus. Hearing a request for it though certainly gets me thinking about it again... stay tuned!

MainTrane
  • Guests
  • Last active:
  • Joined: --
I've used several programs to get this functionality:

Grab and Drag - the absolute best. It can do an exact one-to-one simulation of the scroll bar!! only for FireFox

MouseIMP Pro Live! - what I used to use, works smoothly. Loved it on 32-bit XP doesn't work in x64. free but no longer developed

Pointix Scroll++ - good program but performs exactly like a scroll wheel (I already have scroll wheels on my mice). old pay program, now abandonware

Scroll Navigator - very buggy, mouse cursor inadvertently jumps over to the scroll bar plus it interferes with middle/right-clicks depending on which button you choose

MoScroll - can only use right-click button, can't adjust scrolling rate & operation not the smoothest. no longer developed

Your script seems to be the best solution!
I prefer to use MButton (assigned to the third side button on both my G500 & MX1100). How do I get the 'DragSkip' to work with the MButton? I tried Middle instead of Right but it didnt work.
One last thing. The script works great as is, but I would love to get the exact 1-to-1 scrollbar functionality that's in the 'Grab and Drag' Firefox extension (scrollbar simulation instead of scroll wheel simulation). For example when at the end of whatever grabbing from the top and dragging all the way down would always bring me through the entirety of whatever, just like pulling the scrollbar from bottom to top.

Thanks again for this great script!

cheek
  • Members
  • 71 posts
  • Last active: Jun 21 2014 03:24 AM
  • Joined: 01 Apr 2009

Your script seems to be the best solution!

Thanks for the kind words! :)
I've tried many of these other programs myself, and think this implementation is the best too ;)

I prefer to use MButton (assigned to the third side button on both my G500 & MX1100). How do I get the 'DragSkip' to work with the MButton? I tried Middle instead of Right but it didnt work.

That should have done it..
According to http://www.autohotke...mands/Click.htm and http://www.autohotke.../Send.htm#Click you should be able to use any of
Click Middle
Send {Click Middle}
Send {MButton}


I would love to get the exact 1-to-1 scrollbar functionality ... scrollbar simulation instead of scroll wheel simulation

Unfortunately this isn't very feasible for this script; the only way that works is to know how long the document is i.e. "how many scrolls" it takes to go all the way to the bottom or top. I have seen other AHK scripts that that access the scrollbar information directly (and this is how the ffx extension is able to do it), but its not very reliable across applications. The script works well now because it does not rely on this information, it just requests the app to scroll. That is to say, most applications respect the WM scroll requests, but do not implement it in a standard way.

I have considered an addition where the scroll speed would automatically adjust, on windows where scrollbar info is available, using the default otherwise; I have not yet looked into this, but I'll keep it in mind :)

MainTrane
  • Guests
  • Last active:
  • Joined: --
Don't spend too much time worrying about that, I've adjusted speed and edge scrolling settings to the point where it works great in just about any scenario :D. The only instance I've come across where it would really be necessary now is with image programs (ACDSee & WindowsLivePhotoGallery specifically).

The only way I can get standard middle-clicks is to either hold down Ctrl or disable DtS.

:!:I've also had quite a few instances where dragging stops working after one has just been performed (middle-clicking is still disabled). I shift focus to another window then back to re-initialize DtS (I have auto-activate-window-under-mouse-cursor-without bringing-window-to-front enabled; Win7 x64). Unfortunately I ran into a magnified version of this while scrolling down to read your reply (DtS completely stopped working, middle-clicks were performed as if DtS was not running). I had to reload the script.

MainTrane
  • Guests
  • Last active:
  • Joined: --

That should have done it..
According to http://www.autohotke...mands/Click.htm and http://www.autohotke.../Send.htm#Click you should be able to use any of

Click Middle
Send {Click Middle}
Send {MButton}

I've tried all of the above but none work.
I know the command is correct because if i set it to Click Right, my MButton will bring up the right click menu with DtS disabled. When set to Click Middle and DtS disabled I get the expected middle-click.
Nothing ever happens with DtS enabled though, even making sure not to budge the mouse a pixel. Tried several press durations too, from extremely quick to holding for a couple seconds.

cheek
  • Members
  • 71 posts
  • Last active: Jun 21 2014 03:24 AM
  • Joined: 01 Apr 2009
I just edited my copy, making the changes I described in an earlier post, on how to change the binding key. I'm thinking that the next update is definitely going to include better handling of settings, including the binding key.

I changed the hotkey declarations, and the DragSkip label, to:
MButton::
    ...
MButton Up::
    ...
DragSkip:
    ...
    Click Middle

and it seemed to work fine. I was seeing normal wheel-click behavior--firefox was the only app I could think of that used middle click--specifically the drag-lock behavior for scrolling, and tab-closing with middle click on the tab.

When set to Click Middle and DtS disabled I get the expected middle-click. Nothing ever happens with DtS enabled though, even making sure not to budge the mouse a pixel. Tried several press durations too, from extremely quick to holding for a couple seconds

Moving the mouse shouldn't matter, activation of the drag v.s. standard click is purely time based. You want to press it quickly, for the normal behavior. Click-release under the DragDelay and you should get the normal behavior, click-hold beyond that time should start a drag. I'd also try increasing the DragDelay setting.. Maybe its just that the wheel is a physically bigger button and takes you a bit longer to press than RButton.

It could also have something to do with the fact that your MButton is assigned to another button?.. how are you doing the binding? with ahk? What if you tried to Click or Send XButton instead? You might also be able to do something with a ScanCode or VirtualKeycode for more complex mouse/keyboard setups http://www.autohotke...htm#SpecialKeys



I've also had quite a few instances where dragging stops working after one has just been performed (middle-clicking is still disabled). I shift focus to another window then back to re-initialize DtS (I have auto-activate-window-under-mouse-cursor-without bringing-window-to-front enabled; Win7 x64). Unfortunately I ran into a magnified version of this while scrolling down to read your reply (DtS completely stopped working, middle-clicks were performed as if DtS was not running). I had to reload the script.

Not quite sure I understood all of that, but I have found that every once in a while I get some sticking, either refusing to start or stop a drag, usually the former after recent updates. I don't think switching windows or auto-activate on hover should be a problem; DtS does not respect the active window, it grabs the window id under the mouse when you click, and sends the messages there, so it should work even if you don't auto-activate. Are you using the ConfineToTarget option? Does ANYONE use that?

All in all I get reliable results, I always assume any sticking is just my system burping, an application lagging, or otherwise having bugs. I have noticed a few applications (Notepad++) that behave strangely, but I think that has more to do with how it handles multiple monitors.

You can also keep an eye on the tray icon, to show you exactly when the drag is started and stopped; that might give you a bit more insight. The hand grips down a bit, if you hadn't noticed.

MainTrane
  • Guests
  • Last active:
  • Joined: --
I doubled the DragDelay from 100ms to 200ms to get middle-clicks with DtS enabled :idea: :oops:
:phew: Really use the standard middle-click for a lot (closing and minimizing all programs/windows/tabs).

It doesn't seem to recognize being held though. Tried disabling DtS and heavily increasing DragDelay to no avail. To site specific examples I'm talking about holding MButton while scrolling the wheel (changes volume via 'VoluMouse') and temp-using other drag apps such as 'Grab and Drag'. MouseIMP pulled these acts off somehow.

MainTrane
  • Guests
  • Last active:
  • Joined: --

Exactly. Right now, if you click-hold, and don't move the mouse it still captures your right click. For example, Right-hold+Left click (like a rocker gesture) doesn't work. If there's no mouse movement, the right click should always happen.

I understand the motivation to allow normal right click behavior if you click and hold, but do not move the mouse.... I just don't understand how this would technically work, without interefering with other usage. I'm going to think more about how this might work, and followup with some changes and/or another post discussing this..

I think that last bit I mentioned is the same as this issue you discussed with DarKcyde.

MainTrane
  • Guests
  • Last active:
  • Joined: --

...Unfortunately I ran into a magnified version of this while scrolling down to read your reply (DtS completely stopped working, middle-clicks were performed as if DtS was not running). I had to reload the script.

... All in all I get reliable results, I always assume any sticking is just my system burping, an application lagging, or otherwise having bugs. I have noticed a few applications (Notepad++) that behave strangely, but I think that has more to do with how it handles multiple monitors.

You can also keep an eye on the tray icon, to show you exactly when the drag is started and stopped; that might give you a bit more insight. The hand grips down a bit, if you hadn't noticed.

This part is definitely not a sticking issue and occurs with a couple other apps that respond to mouse gestures on my system (MouseExtender & Switcher). Both are really great BTW; best way to launch and switch between apps respectively.

cheek
  • Members
  • 71 posts
  • Last active: Jun 21 2014 03:24 AM
  • Joined: 01 Apr 2009
Good afternoon all! I just posted an updated version of DtS which adds a number of new features.

Easier Customization of binding key
Using dynamic hotkey labels now, you should be able to edit the single app-settings variable "Button". All other hotkeys, DragSkip, etc are represented in this variable. Change to any valid AHK hotkey.

Toggle Slow Mode
I posted earlier a little snippet to toggle the scroll speed between slow & fast. This has been included in the latest release, and is the new default double-click action. As always, feel free to change this action using the methods mentioned in an earlier post.

Movement Checking
Per many requests (Airblaster, MainTrane, DarKcyde..), I have added an option (disabled by default) to abort/skip dragging if the mouse button is held but not moved. It is configurable with new options, MovementCheckDelay and MovementThreshold. If the binding button is held for MovementCheckDelay and is not moved further than MovementThreshold pixels from the click location, the click is handled as normally and the binding button is virtually held down until you release it. Default behavior is to set MovementCheckDelay LONGER than DragDelay so that this does not interfere with actually dragging the document.

For those that requested this feature, grab the new version and try it out. Please let me know if this solves the issues you were having, around other gestures, rocker actions, etc.

DarKcyde
  • Guests
  • Last active:
  • Joined: --
Thanks cheek, it works!

A minor thing that annoyed me though. If you hold still too long after clicking, you don't start the dragscroll. I fiddled w/ the code a bit, basically turned MovementCheck into a poller like DragStart. Made one or two edits elsewhere, but I think this is all that's required.

MovementCheck:
Critical
    ; Calculate the distance moved, pythagorean thm
    MouseGetPos, MoveX, MoveY
    MoveDist := sqrt((ClickX - MoveX)**2 + (ClickY - MoveY)**2)
   

    if (MoveDist <= MovementThreshold)
    {
      ; if we havent moved past the threshold,
      ; abort the drag, update status, start hold
      SetTimer, DragStart, Off
      SetTimer, MovementCheck, % -1 * Abs(PollFrequency)  ;schedule next poll
      DragStatus := DS_HOLDING
      If !GetKeyState(Button)  ;Press the button if its not down already
        Send, {%Button% Down}
    }
    else   ;we're over MovementThreshold, reverse above
    {
      SetTimer, DragStart, % -1 * Abs(PollFrequency)
      SetTimer, MovementCheck, Off
      DragStatus := DS_NEW
    }
Return

With this you can click-hold, wait a bit, then decide to start scrolling. The right click is still generated, so you get an annoying menu, which I might try cleaning up later.

Also noticed I can easily right click and get nothing at all, probably just have to fiddle with the delays.

cheek
  • Members
  • 71 posts
  • Last active: Jun 21 2014 03:24 AM
  • Joined: 01 Apr 2009
I think what you're seeing is an unresolved click, where you send Button down, but never release it. I was able to generate this issue with your mod by click-holding w/o movement, to start the "holding" state (sending button down), then starting the drag, the drag handler completes with DS_Handled w/o ever sending button up.



There are a number of ways to implement this..
What we're really talking about is having two actions on the same input (click-hold): dragging, and simulating the button held down. Movement is potentially valid in both actions e.g. a context-menu group selection, which I actually used to use before DtS.

1) Timeline (my approach)
Holding the button without movement for different amounts of time has different actions
e.g.

Time
|---------|-----------------------------|-------------------------------------->
0         A                             B 
Click  DragThreshold             MovementCheckDelay
If at/before A, the mouse has been relased, a normal click-release is sent. The drag is offically started at A; if between then and B, the mouse is moved, dragging takes over. If at B the mouse has still not moved, send & hold the original key until its released.

This approach should work for any button and never leave a click un- or partially-consumed, since its just an extension of the existing timeline model. Any holds beyond B are intentionally being held and should NOT be 'consumed'; a context menu is acceptable, or desirable.

You can also fiddle with the delays, DragDelay and MovementCheckDelay are intentionally separately configurable; changing these can alter the behavior quite a bit. You can increase the CheckDelay to force you to wait pause for the holding state, which i thought might be suitable for some usages. You can also swap the order of A & B by setting the CheckDelay to LESS than DragDelay, giving yourself just enough time for something like a rocker action, but probably not suitable for something like Volumouse. You can also set the Threshold to 0, which changes the experience.. (I should have made this the default. ..next update)

2) The easiest approach
Unfortunately I hadn't thought of until after I had the bulk of my changes done, is simply to BOTH hold the button down, and to drag. This approach does not "consume" the click, which means that you will be sending random input to some application; in the case of RButton you'll see the behavior you describe in opening up context menus. Still, not a bad idea, depending on your needs, and the binding button you choose. A toggle state keyboard key like ctrl, alt, shift may work well.


3) Minimum Speed
If at any time your drag speed is below a threshold (0 maybe), HOLDING is entered, whereas faster movement is dragging. This might also work ok, but has the same problem in 'consuming' the click. I also like being able to click and hold a document, scrolling it in chunks, as I read; this behavior would always be opening those spurious context menus.


4) Area Based (your approach)
As long as you are within a Threshold of the original click location, hold the button down. As soon as you leave the threshold, start dragging. This actually works pretty well, with a few drawbacks. This setup is a race condition (mine is too, actually), forcing you to start your drag quickly, so that you don't falsely send button down, leading to the state problem you were seeing. Since DragStatus is current status only, you'd have to separately track whether you'd previously held for this click or not. Depending on the settings and your usage pattern, the race condition may cause a lot of those false clicks.


I'm sure there are other approaches I haven't thought of too... Each with their advantages and disadvantages. I tried to pick an approach that would be the most generally usable. Feel free to give any of these a go ;)

MainTrane
  • Guests
  • Last active:
  • Joined: --
Thanks for the update cheek, after using DtS for the last few days I haven't been experiencing those hiccups described earlier :O . The only time drag to scroll lost its hook into the mouse since then was when my RAM usage was maxed out; understandable. So it's not having that problem with the same severity of the other 2 programs I mentioned.

The new update does exactly what I hoped for, I like that it defaults to the buttons default held behavior when held past the 'MovementCheckDelay'. Thank you :D

MainTrane
  • Guests
  • Last active:
  • Joined: --
Ran into an issue, the updated script doesn't play well with rocker gestures that involve the RButton, when the user assigns the drag button to something else (MButton). My LButton>RButton in Firefox should reload the page, I get the right-click menu instead; Rbutton>LButton should stop a page from loading, instead it reloads the page (I actually think it does both, sends the stop command then follows it with the reload command).