This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
cyanisaac's profile picture

Mouse cursor pos is off with window

Started by cyanisaac, 19 June 2015 - 04:04 PM
cyanisaac #1
Posted 19 June 2015 - 06:04 PM
In my OS, I am testing having two seperate windows. One is running a shell, and the other is running a sort of information bar.

The issue is this: When the infoBar window is at the bottom, the shell area's cursor position is reported normally. However when it is at the top, the cursor position is reported one below where the mouse really is.

I need a solution that will override this check for other programs as well - it affects the entire shell. If there is a way to fix this please let me know.

Thanks!
Edited on 19 June 2015 - 04:05 PM
Cross_Sans #2
Posted 19 June 2015 - 06:31 PM
Please post a image, and the code (on pastebin if possible) !
And i try to resolve this :)/> !
Bomb Bloke #3
Posted 20 June 2015 - 08:57 AM
Mouse click events always return relative to the top left of a computer's native display. They don't care whether you've redirected to some other terminal object, such as a window.

To deal with this, you'd need to either change the code used for pulling events, or change the code used for pushing events. Multishell, for example, goes with the latter solution - if a script that it's running in one of its windows wants to pull a mouse click event, then it may modify that event before pushing it to that script.

I'll assume you're using the parallel API to handle your processes. Taking the "push" approach, you'd instead write your own coroutine manager.

The other option, "pulling", would best be done by overriding os.pullEventRaw(), so that it checks whether it's about to return a mouse click event and modifies it before doing so. Assuming you never move your windows, and aren't interested in infoBar clicks, this is a lot simpler - you just add a bit to the mouse's location before returning, eg:

local infoBarLines = 1

local oldPER = os.pullEventRaw

function os.pullEventRaw(filter)
	local result
	
	repeat
		result = {oldPER(filter)}
		
		if result[1] == "mouse_click" then  -- If the event we're pulling is a mouse click,
			if result[4] < infoBarLines + 1 then
				result = nil        -- Discard it if it was on the infoBar.
			else
				result[4] = result[4] -- infoBarLines  -- Or modify it if it wasn't.
			end
		end
	until result
	
	return unpack(result)
end

-- Rest of your script here.

os.pullEventRaw = oldPER

If you're moving windows around, or redirecting to windows which are defined within windows, etc, it becomes significantly more complex - but odds are this'll suit your purposes.
Edited on 20 June 2015 - 08:23 AM
MKlegoman357 #4
Posted 20 June 2015 - 10:44 AM
Note that there is no need for the 'repeat' loop there, it will run only once anyway.

EDIT: See below
Edited on 20 June 2015 - 09:31 AM
Bomb Bloke #5
Posted 20 June 2015 - 11:01 AM
Not if the user clicks on the infoBar, it won't.
MKlegoman357 #6
Posted 20 June 2015 - 11:31 AM
Not if the user clicks on the infoBar, it won't.

Oh, missed that if which sets 'result' to nil.