i’ve broken this problem down into something much less complicated. after reading the following bits of code and documentation i was inspired.
////////////////////////////////////////////////////////////////////
// Function: WindowFramework::get_mouse
// Access: Public
// Description: Returns the node in the data graph corresponding to
// the mouse associated with this window.
////////////////////////////////////////////////////////////////////
NodePath WindowFramework::
get_mouse() {
if (_mouse.is_empty()) {
NodePath mouse = _panda_framework->get_mouse(_window);
// Create a MouseWatcher to filter the mouse input. We do this
// mainly so we can constrain the mouse input to our particular
// display region, if we have one. This means the node we return
// from get_mouse() is actually a MouseWatcher, but since it
// presents the same interface as a Mouse, no one should mind.
// Another advantage to using a MouseWatcher is that the PGTop of
// aspect2d likes it better.
PT(MouseWatcher) mw = new MouseWatcher("watcher");
mw->set_display_region(_display_region_3d);
_mouse = mouse.attach_new_node(mw);
}
return _mouse;
}
the important (imo) bit of the above code is the in-code comment about performing the action ‘so we can constrain the mouse input’ etc.
#### from (the end of) showbase's setupMouse() call
# Tell the gui system about our new mouse watcher.
self.aspect2d.node().setMouseWatcher(mw.node())
self.aspect2dp.node().setMouseWatcher(mw.node())
mw.node().addRegion(PGMouseWatcherBackground())
the above code is that which my file mimics (or attempts to).
////////////////////////////////////////////////////////////////////
// Function: PGTop::set_mouse_watcher
// Access: Published
// Description: Sets the MouseWatcher pointer that the PGTop object
// registers its PG items with. This must be set before
// the PG items are active.
////////////////////////////////////////////////////////////////////
void PGTop::
set_mouse_watcher(MouseWatcher *watcher) {
if (_watcher_group != (PGMouseWatcherGroup *)NULL) {
_watcher_group->clear_top(this);
}
if (_watcher != (MouseWatcher *)NULL) {
_watcher->remove_group(_watcher_group);
}
_watcher = watcher;
_watcher_group = (PGMouseWatcherGroup *)NULL;
if (_watcher != (MouseWatcher *)NULL) {
_watcher_group = new PGMouseWatcherGroup(this);
_watcher->add_group(_watcher_group);
}
}
‘This must be set before the PG items are active.’ makes me a little nervous.
now i believed that setMouseWatcher() could be used to bind a raw mouse to behave the same way that the system mouse does, and ultimately ‘replace’ the system mouse for a given DisplayRegion. that is, report ‘render2d coordinates’ when the pointer is over the panda window and fail the hasMouse() call when outside the window. here’s what i did (full file):
from pandac.PandaModules import *
## loadPrcFileData('','read-raw-mice 1') #NOTE: i get the same results if this function is called or not
import direct.directbase.DirectStart
from direct.task import Task
def u(task):
for i,mw in enumerate(base.pointerWatcherNodes):
if mw.hasMouse():
print i,mw.getMouseX(),mw.getMouseY()
else:
print i
return Task.cont
taskMgr.add(u,'update')
def useFirstRawMouse():
base.pointerWatcherNodes[0].clearRegions()
aspect2d.node().setMouseWatcher(base.pointerWatcherNodes[1])
base.pointerWatcherNodes[1].addRegion(PGMouseWatcherBackground())
here’s what happened instead. running python and importing this file, then running did the expected thing for base.pointerWatcherNode[0]. pointerWatcherNode[1:], however always print (unbounded) coordinates to console and don’t update those coordinates unless the window has focus.
if you break out to the python shell and then call the useFirstRawMouse() function, then run again… nothing changes. well, that’s not totally true. inspecting the base.pointerWatcherNodes list reveals that system pointer now claims to have 0 regions, while the first raw mouse has 1.
but the data that’s printed to console is exactly the same: 0 shows ‘good’ coordinates as long as the pointer’s in frame and nothing otherwise (whether the window has focus or not) and the other pointers continue to dispaly their unbounded coordinates (which only change if the panda window has focus).
is this the correct behavior? it’s certainly not the behavior i expected.
btw, i’m not sure of the status of unifying the mouse interface across platforms, so let me say this is all under win(32)dows.
jeremy