I've got a fairly new Apple Mouse. It doesn't have a traditional scroll wheel, instead, it works like a touch device. I can swipe and tap, and swiping works as a regular mouse wheel would. If I swipe it up or down, it acts like I'd keep the wheel spinning. Tap it acts like I stop the spinning wheel. It's fairly sensitive, so not very easy to use in all applications, but it works.
I was trying to get the mouse wheel to work in LÖVE, but there's a slight problem. In my tests, I have determined that when using the mouse wheel, mousepressed() and mousereleased() are triggered at the exact same time, while mouse.isDown() doesn't pick up the action at all. So I cannot get the wheel to work using isDown(), but I also can't get it to work with the callbacks, because it doesn't even see the mouse as being activated for even one frame. I can see the wheel is activated, but I can't see when it's not in use anymore, so assigning a 'wu' variable in mousepressed() and then setting that variable back to nil in mousereleased() tells me that the wheel is not activated at all.
I don't think there's any way around this, but I'm just wondering, seeing as the wheel works as normal in other applications, what does LÖVE do differently that only makes it appear to work as a superfast spike?
Apple Mouse wheel not picked up
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- DaedalusYoung
- Party member
- Posts: 407
- Joined: Sun Jul 14, 2013 8:04 pm
Re: Apple Mouse wheel not picked up
Since the Apple mouse is a multi-touch device, the simple scroll wheel API can not represent all the information that the mouse sends. SDL 1.2 just does the minimum with scroll wheel events and all you get are impulses.
I'm guessing the drivers goes into some sort of legacy mode and just emulates a simple scroll wheel. The more impulses you get, the faster it scrolls. Set up a variable that has the actual count of these impulses and a variable that slowly approaches this value over time. That should get you the swiping effect.
I do hope your driver does handle it like that anyway and I understood your problem correctly.
You can also try out a development build for LÖVE. If the callbacks were already adjusted for SDL 2,then you even get horizontal movement (not exposed). Still no multi-touch stuff, though.
I'm guessing the drivers goes into some sort of legacy mode and just emulates a simple scroll wheel. The more impulses you get, the faster it scrolls. Set up a variable that has the actual count of these impulses and a variable that slowly approaches this value over time. That should get you the swiping effect.
Code: Select all
function love.load()
target_position = 0
display_position = 0
-- Adjust this if scrolls too slow or fast.
scroll_speed = 25
end
function love.mousepressed(x, y, b)
if b == "wu" then
target_position = target_position + scroll_speed
elseif b == "wd" then
target_position = target_position - scroll_speed
end
end
function love.update(dt)
local diff = target_position - display_position
if diff ~= 0 then
if math.abs(diff) < 0.01 then
display_position = target_position
else
display_position = display_position + diff * scroll_speed * dt
end
end
end
function love.draw()
local num_lines = 16
local line_distance = 40
local wrap_around = num_lines * line_distance
for i = 1, num_lines, 2 do
local p = (i * line_distance + display_position) % wrap_around - line_distance
love.graphics.rectangle("fill", 0, p, 800, line_distance)
end
end
You can also try out a development build for LÖVE. If the callbacks were already adjusted for SDL 2,
Last edited by Boolsheet on Tue Nov 12, 2013 8:31 am, edited 1 time in total.
Shallow indentations.
- slime
- Solid Snayke
- Posts: 3143
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Apple Mouse wheel not picked up
That's one thing I haven't changed (or rather, I preserved backwards compatibility for it) actually - LÖVE's mousewheel events are still part of the mousepressed event, only wheel-up and wheel-down are sent, and there's no way to get the amount scrolled.Boolsheet wrote:You can also try out a development build for LÖVE. If the callbacks were already adjusted for SDL 2, then you even get horizontal movement. Still no multi-touch stuff, though.
Maybe I'll see if I can add SDL's new functionality nicely.
- DaedalusYoung
- Party member
- Posts: 407
- Joined: Sun Jul 14, 2013 8:04 pm
Re: Apple Mouse wheel not picked up
Thanks, I'll look into it. Can mousepressed() get called more than once per frame? Likely the mouse is sending quick pulses, as you said, that other apps are able to pick up. If it gets 500 pulses per second, it moves fast, if it gets 120 pulses per second, it is slow (or something like that). If mousepressed() is able to pick that up, then that might work just fine after all.
[edit]
Well, I tested that and it's indeed not the case. I can get the scrolling to work by adding and subtracting in the mousepressed() function, and that looks alright, but it indeed doesn't use the proper velocity. But at least it scrolls, so that's a good thing, too bad mouse.isDown() doesn't see it.
If you want to play with this yourself, I used this testcode:
It shows when the wheel is activated by colour and flickers when it is slowing down.
[edit]
Well, I tested that and it's indeed not the case. I can get the scrolling to work by adding and subtracting in the mousepressed() function, and that looks alright, but it indeed doesn't use the proper velocity. But at least it scrolls, so that's a good thing, too bad mouse.isDown() doesn't see it.
If you want to play with this yourself, I used this testcode:
Code: Select all
function love.load()
posy = 300
prevy = { 300, 300 }
wheelcolour = {
line = { 192, 192, 192 },
fill = { 255, 255, 255 }
}
love.graphics.setLineWidth(4)
end
function love.update(dt)
if love.mouse.isDown('l') then
mousedown = 'l'
elseif love.mouse.isDown('r') then
mousedown = 'r'
elseif love.mouse.isDown('wu') then
mousedown = 'wu'
elseif love.mouse.isDown('wd') then
mousedown = 'wd'
end
if prevy[1] == posy and prevy[2] == posy then
wheelcolour.line = { 192, 192, 192 }
wheelcolour.fill = { 255, 255, 255 }
elseif prevy[1] ~= prevy[2] and prevy[1] == posy then
wheelcolour.line = { 192, 192, 0 }
wheelcolour.fill = { 255, 255, 0 }
end
prevy[2] = prevy[1]
prevy[1] = posy
end
function love.draw()
love.graphics.setColor(255, 255, 255)
love.graphics.print("mousedown: " .. tostring(mousedown), 32, 32)
love.graphics.print("mousepressed: " .. tostring(mousepressed), 32, 48)
love.graphics.print("mousereleased: " .. tostring(mousereleased), 32, 64)
love.graphics.setColor(wheelcolour.fill)
love.graphics.circle('fill', 400, posy, 16, 18)
love.graphics.setColor(wheelcolour.line)
love.graphics.circle('line', 400, posy, 16, 18)
end
function love.mousepressed(x, y, button)
mousepressed = button
if button == "wu" then
posy = posy - 1
wheelcolour.line = { 192, 0, 0 }
wheelcolour.fill = { 255, 0, 0 }
elseif button == "wd" then
posy = posy + 1
wheelcolour.line = { 0, 192, 0 }
wheelcolour.fill = { 0, 255, 0 }
end
if posy < 0 then posy = 0 elseif posy > 599 then posy = 599 end
end
function love.mousereleased(x, y, button)
mousereleased = button
end
Re: Apple Mouse wheel not picked up
Is my example code also not producing a satisfactory result? Since all you get are impulses and you have no idea what the user settings are, you kind of have to fiddle with it. Or give the user an option to change the speed.
There is no concept of "holding the scroll wheel down". SDL 1.2 jammed the scroll wheel into the mouse button event and LÖVE follows this behaviour. This is somewhat wrong and it indeed seems to confuse people. SDL 2.0 has its own separate wheel motion event for this so it's a bit cleaner.
Because the concept of holding down a scroll wheel is invalid, SDL 1.2 just fires a release event immediately after the press to make it consistent with the rest of the button events. love.mouse.isDown can never give you true for a scroll wheel because it doesn't exist.
There is no concept of "holding the scroll wheel down". SDL 1.2 jammed the scroll wheel into the mouse button event and LÖVE follows this behaviour. This is somewhat wrong and it indeed seems to confuse people. SDL 2.0 has its own separate wheel motion event for this so it's a bit cleaner.
Because the concept of holding down a scroll wheel is invalid, SDL 1.2 just fires a release event immediately after the press to make it consistent with the rest of the button events. love.mouse.isDown can never give you true for a scroll wheel because it doesn't exist.
Shallow indentations.
- DaedalusYoung
- Party member
- Posts: 407
- Joined: Sun Jul 14, 2013 8:04 pm
Re: Apple Mouse wheel not picked up
Your code feels a bit better while scrolling, but it doesn't handle tapping to hold very well; it always slows down gradually instead of instant stopping.
On further experimentation, it also seems to work the wrong way round, increasing speed the longer the mousewheel is spinning, while the Apple Mouse sort of works like giving it an impulse, letting the wheel spin and letting it slow down naturally. How fast this spinning starts depends on how fast you swipe the mouse. Think of it literally like moving a free spinning wheel, give it an impulse and it will spin fast and gradually slow down. Put your hand on it while it's spinning and it will stop instantly.
Of course, there is no way of knowing the initial swipe speed, unless you can accurately count the number of pulses per frame.
I'm thinking the mouse emulates this by giving a high frequency of mouse wheel pulses at first, which slows down over time until it reaches 0 (like fading LEDs is done by pulse width modulation). And especially these first pulses are not all picked up, as LÖVE only counts 1 pulse per frame (while in reality, the mouse may be giving off 10 pulses per frame). In my code, it is obvious the frequency decreases as the spinning slows down, because it flickers the colours. This is not visible for high speed spins, because there are more pulses than frames.
On further experimentation, it also seems to work the wrong way round, increasing speed the longer the mousewheel is spinning, while the Apple Mouse sort of works like giving it an impulse, letting the wheel spin and letting it slow down naturally. How fast this spinning starts depends on how fast you swipe the mouse. Think of it literally like moving a free spinning wheel, give it an impulse and it will spin fast and gradually slow down. Put your hand on it while it's spinning and it will stop instantly.
Of course, there is no way of knowing the initial swipe speed, unless you can accurately count the number of pulses per frame.
I'm thinking the mouse emulates this by giving a high frequency of mouse wheel pulses at first, which slows down over time until it reaches 0 (like fading LEDs is done by pulse width modulation). And especially these first pulses are not all picked up, as LÖVE only counts 1 pulse per frame (while in reality, the mouse may be giving off 10 pulses per frame). In my code, it is obvious the frequency decreases as the spinning slows down, because it flickers the colours. This is not visible for high speed spins, because there are more pulses than frames.
Who is online
Users browsing this forum: glitchapp and 1 guest