Bump. I'm working on a project that would benefit greatly from this.
Now that my library is a patched security hole, could we get some actual support here? Nearly every desktop computer in the world has a pointer. Maybe we could start supporting that at some point?
Mouse pixel_x/y should not really be what we are after. Those variables belong to procedures that operate on the server-side.

Unfortunately, in DM, everything the mouse does is constrained to either the client object or an atomic object, which severely limits how well developers can make use of the mouse.

What we really need is a more general solution, that doesn't result in network lag. There should be something based around the mouse that is analogous to the current keyboard macros. What if every window simply had a mouse-position parameter, that gets updated on the client-side? With something like this, all you would have to do is call winget(usr, "mainwindow", "mouse-position") each tick, to add mouse tracking to your game. Would this be a good approach, or would winget() have too much overhead for something like mouse tracking?
In response to Multiverse7
Although it could be useful to know the mouse's absolute position in the computer screen, all I need is a variable or two (preferably not in string form) describing the mouse's position over the map, with (0, 0) being the bottom-left pixel. It would scale with the map control's icon-size or stretching.

Basically, Forum_account's Mouse Position library without its limitations.
I was actually suggesting that the parameter be specific to a window, not necessarily the whole computer screen. I guess there could instead be a parameter specific to each map control, where the mouse coordinates are captured relative to the view-size and icon-size. Really, there could be a mouse-position param for any given control that has focus. If a control doesn't have focus, then its mouse-position param is null. The map is definitely the priority though.

The problem with it being a variable is that updating a variable results in network lag, and in the case of something like mouse coordinates, a lot of it. As Lummox JR mentioned, not everyone will use mouse tracking. I suggested using a parameter, because theoretically, a param can be updated by the client without any influence on the network. Unfortunately, this would probably require that we parse the text with text2num(). I don't know if actual numbers even technically exist on the client-side. This may just be something we will have to deal with, if we ever hope to have mouse tracking in BYOND.

I'm trying to think of a real solution, and I'm pretty sure procs and vars will be of no help in this matter. This basically requires something else altogether, like a param, unless we ever get some kind of special client/world.
In response to Multiverse7
I agree with your client-side suggestion, just not with using winget(), since it only returns strings. Unless it could be made so it returns something else. I just don't want to have to parse something like "[x],[y]".

edit: This would reflect what the current mouse parameters do.
var mouse_x = text2num(winget(player, null, "mouse-x"))
var mouse_y = text2num(winget(player, null, "mouse-y"))
// Ideally, the winget() would return a number so I wouldn't have to use text2num().


// or
var mouse_info[] = winget(player, null, "mouse-position")
// would return a list like
list(
// This would represent the mouse's screen_loc.
// screen_loc = "[x]:[px],[y]:[py]"
"mouse-x" = x,
"mouse-y" = y,
"mouse-px" = px,
"mouse-py" = py,

// This would be the mouse's screen coordinates.
// (0, 0) is the bottom-left pixel.
// (this is what I'd use most often)
"mouse-sx" = (x - 1) * tile_width + px,
"mouse-sy" = (y - 1) * tile_height + py,
)

// Then, like with the params in the Mouse Events,
var mouse_sx = text2num(mouse_info["mouse-sx"])
etc.

In response to Kaiochao
That looks pretty good. We just need to know if it's actually possible to make this happen.
Fetching coordinates is not viable as it will always be late.
In response to Multiverse7
Multiverse7 wrote:
The problem with it being a variable is that updating a variable results in network lag, and in the case of something like mouse coordinates, a lot of it. As Lummox JR mentioned, not everyone will use mouse tracking. I suggested using a parameter, because theoretically, a param can be updated by the client without any influence on the network. Unfortunately, this would probably require that we parse the text with text2num(). I don't know if actual numbers even technically exist on the client-side. This may just be something we will have to deal with, if we ever hope to have mouse tracking in BYOND.

The client can update all the params it wants, but the only way to grab them would involve the network. At any given time it's perfectly possible to grab info on where the mouse cursor is, what atom it's over, and where; but that info is of no use to the server unless it's sent.

I'd be perfectly happy setting some kind of flag to indicate the position should always update on a given atom rather than only changing if the hit test changes to a new atom, but it's a question of how to set that flag. Obviously that should be the exception rather than the rule, because most games won't use it.
In response to Lummox JR
Lummox JR wrote:
The client can update all the params it wants, but the only way to grab them would involve the network. At any given time it's perfectly possible to grab info on where the mouse cursor is, what atom it's over, and where; but that info is of no use to the server unless it's sent.

So would winget() be a particularly bad way to send that info?


I'd be perfectly happy setting some kind of flag to indicate the position should always update on a given atom rather than only changing if the hit test changes to a new atom, but it's a question of how to set that flag. Obviously that should be the exception rather than the rule, because most games won't use it.

I guess that if it has to be a setting, then a client var would probably be the best way to go about it. There could be cases where you don't always want to track the mouse, so a variable that you could change at runtime would probably be ideal. MouseEntered(), MouseExited(), and MouseDrag() would be called conditionally, depending on the setting of this variable.

This would also allow you to disable mouse tracking altogether when you don't need it! That means such a setting could actually reduce lag for any game that uses mouse tracking. Currently, when you define those procs in the client, it puts a permanent burden on the network, so such a var could lift that from certain clients when it's not needed.

Basically, this is the idea:
client
mouse_update_mode = MOUSE_UPDATE_ATOM
//This would be the default setting.
//The mouse procs are called based only on the mouse_opacity of atoms.

mouse_update_mode = MOUSE_UPDATE_PIXEL
//This setting would call the corresponding mouse procs at the passing of a single pixel.

mouse_update_mode = null
//This does exactly what you think. It disables all defined mouse tracking procs,
//with the exception of MouseDown() and MouseUp().

This is an odd variable, so I'm not really sure what to name it, or how it should be assigned values. This is just to show the concept of it. A variable is probably the only way to have an actual "setting" for something like this, because it would have to work with the existing mouse procs.
In response to Multiverse7
Multiverse7 wrote:
So would winget() be a particularly bad way to send that info?

Gads yes. I think if this is done at all it should be done via existing mouse procs, just with something to trigger updates on small changes.

I guess that if it has to be a setting, then a client var would probably be the best way to go about it. There could be cases where you don't always want to track the mouse, so a variable that you could change at runtime would probably be ideal. MouseEntered(), MouseExited(), and MouseDrag() would be called conditionally, depending on the setting of this variable.

I dislike the idea of adding a var only for this purpose; that kind of thing tends to be kind of wasteful, and this is basically a very niche feature.
In response to Lummox JR
So if it can't be a proc, a param, or a variable, then how can this work? I'm about out of ideas. All that's left is to design a special datum made just for the mouse, but I don't see how that could be done without crushing all backwards compatibility.

Also, you may see this as "niche", but to us developers, controls are basically the most important thing.
In response to Lummox JR
I've been using Forum_account's Mouse Position library lately, and it provides client/MouseUpdate(tx, px, ty, py). The arguments are translated from the screen-loc parameter in MouseEntered and MouseDrag.
I always end up converting the arguments to absolute pixel coordinates relative to the bottom-left of the view.
Sometimes I even convert that into an offset from the eye.

Why not just use client/MouseUpdate(), with some form of arguments? If it's not defined, it would be as if the feature doesn't exist, just like most of the other mouse events. If it is, it would be called at the beginning of each tick.

As I said in a previous post regarding the staggering amount of bandwidth,
DM Reference (client/MouseEntered(), atom/MouseEntered(), etc.):
Don't define this unless you need it, because it generates extra communication that is otherwise avoided.
How much extra communication would there be?
How much does it take to seriously impact performance?
I understand that we want this to use as little bandwidth as possible, but I think that you're overestimating the amount of strain it would cause. I had ten people connect to the demo of HDK Mouse And Keys, which amounts to fifty screens worth of data being constantly sent to the server and never an issue.

The way my system set up so that you could call Start/Stop/Pause/ResumeMouseTracking(). StartMouseTracking() would initialize the script and create the browser while StopMouseTracking() would destroy the script and browser. Pause/ResumeMouseTracking() would simply cause the script to pause and resume sending information to the server.

Also, the script only updates roughly every tick of the server and only if the mouse has actually moved since the last iteration.

For retrieving coordinates of the mouse in relation to the client's screen, I used associative lists.

client.mouse_x["map1"] would give you the position of the mouse over the map element, "map1", in the number of pixels from the left of the client's screen. client.mouse_y["map1"] would give you the position of the mouse over the map element, "map1", in the number of pixels from the bottom of the client's screen.

For screen_loc coordinates, I used client.mouse_tx/ty for the number of tiles from the bottom left of the screen, and client.mouse_px/py for the number of pixels from the bottom left of that tile. Therefore, to recreate BYOND's native screen_loc structure, you would do this:

screen_loc = "[mouse_tx["map1"]]:[mouse_px["map1"]],[mouse_ty["map1"]]:[mouse_py["map1"]]

But it's always much more useful to have the coordinates in absolute pixels. That last setup is trash when dealing with screen objects, especially when you can simply do this instead:

screen_loc = "1:[mouse_x["map1"]],1:[mouse_y["map1"]]"

But I digress. Dealing with map coordinates works the same way, save for the associative lists, because there's only ever one map.

So we have:
client
map_x
map_y
map_tx
map_ty
map_px
map_py

I wouldn't mind if the flag we're talking about was a parameter for map elements. We can winset(client, "map1", "mouse-tracking=true") and that can actively populate an associative list defined under client. This way, it's activated on a per-client basis.

I'd also love it if we could get a tracker for the mouse's position on the client's screen so that when I update Ultimate Jigsaw, I can continue using my custom interface.
I suspect that the most consistent way to implement something like this would be a MouseMoved() proc. Like similar mouse procs, its presence or absence could determine whether the message was sent.
Indeed, there is a procedure in my library UpdateMouse() used in the same way. It's arguments are the pixel-based mouse coordinates and the map it's tracking.

Another thing of note is that the mouse has to be tracked when the window is not in focus. I can imagine all sorts issues that would run into otherwise.

I do like the idea of a MouseMoved() procedure. I assume that the parameters would be consistent as well. This would greatly simplify two things for my library: icon-x/y, which are calculated using screen_loc, which isn't fool-proof, virtual_eye, step_x/y, pixel_x/y, et cetera.

Two big issues I foresee with it are the range of coordinates and with which map they correlate. Currently, the mouse parameters only work because of their interaction with atoms. Therefore, the coordinates provided are limited to the range of the client's screen, which is a nightmare for doing things like dragging around screen objects.

Either the coordinates could be generated the same way and allow for negative tile values or they could be generated in a new pixel-based parameter irrespective of screen_loc or. I'd prefer the latter, honestly, as it's a lot cleaner and easier to deal with. Both solutions might actually be the most prudent.

With the map coordinates though, this isn't supported through parameters either way. I would suggest doing just the former of the above solutions.

There's also how the parameters would differentiate coordinate in relation to different maps. I'm at a loss on how to do that gracefully with a text string.
In response to Hiro the Dragon King
Hiro the Dragon King wrote:
Another thing of note is that the mouse has to be tracked when the window is not in focus. I can imagine all sorts issues that would run into otherwise.

I'm not sure I see it. If the window isn't in focus I don't see a point sending updates.

Two big issues I foresee with it are the range of coordinates and with which map they correlate. Currently, the mouse parameters only work because of their interaction with atoms. Therefore, the coordinates provided are limited to the range of the client's screen, which is a nightmare for doing things like dragging around screen objects.

I would use the exact same coordinates we use in MouseEntered(), etc., to maintain consistency.
In response to Lummox JR
Lummox JR wrote:
I suspect that the most consistent way to implement something like this would be a MouseMoved() proc. Like similar mouse procs, its presence or absence could determine whether the message was sent.

The problem with something like a MouseMoved() proc is that once you define it, every connected client is permanently stuck in a state of tracking their mouse and there's nothing you can do to limit the sending of that data. For example, what if you only need to track the mouse when the left mouse button is held down?

Also, this is a different topic, but if we had support for multiple /client type definitions, then all of the current problems with the mouse procs would disappear. I don't know how that would work, or if it would even be feasible at all.
That isn't true. Even with MouseMoved(), you'd still need a winset() flag for the map elements or the screen as a whole. Having it update all of them simply because MouseMoved() is defined just silly, at best.
In response to Hiro the Dragon King
I'd imagine what Lummox meant for MouseMoved() is that it would called whenever the mouse is moved and is over an atom, much like the existing mouse procs. This would mean the map's ID would be included in the screen-loc parameter, and the mouse can only be over one map at a time.

Forum_account's library attempts to read from the screen-loc parameter. This has issues due to INconsistencies.
//  the usual output
"screen-loc=1:23,4:26"

// sometimes the output is like this
"screen-loc=map:1:23,4:26"

It would be really nice if we didn't have to parse a string every time.
Page: 1 2 3