Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » capture mouse and limit all events to window
capture mouse and limit all events to window [message #47441] Tue, 17 January 2017 09:19 Go to next message
slashupp is currently offline  slashupp
Messages: 231
Registered: July 2009
Experienced Member
I'm writing a little game and for it to be functional I need full control over the mouse.
I want to capture the mouse and contain it within a window regardless of how far the mouse is moved.
e.g.: if the mouse is moved far to the right I want to show the pointer as 'stuck' within the right edge
of the window but still responding to vertical movement; all mouse-events(move, clicks, wheel, etc) must
come to my window

how can I achieve this, SetCapture() does not work for this
how/should/can I implement a MouseHook to achieve this?

Also:
how can I set the mouse-pointer to a specific point within my window?
e.g.: if want to (based on some hotkey) place the mousepointer at the center of my window

[Updated on: Wed, 18 January 2017 06:58]

Report message to a moderator

Re: capture mouse and limit all events to window [message #47469 is a reply to message #47441] Fri, 20 January 2017 08:14 Go to previous messageGo to next message
slashupp is currently offline  slashupp
Messages: 231
Registered: July 2009
Experienced Member
I managed to achieve exclusive grab of mouse by modifying Ctrl:

In CtrlCore.h
Added attribute:
    [1049]    bool bcaptureLock;


Added parameters:
    [1050]    bool SetCapture(bool bLock=false);
    [1051]    bool ReleaseCapture(bool bUnlock=false);


In Ctrl.cpp (ctor)
    [596]    bcaptureLock=false;


In CtrlMouse.cpp (changed lines marked with: ///mais )
[301]
Image Ctrl::MEvent0(int e, Point p, int zd)
{
	GuiLock __;
	LLOG("MEvent0 " << Name() << " event: " << FormatIntHex(e, 0) << " point:" << p);
	Ptr<Ctrl> _this = this;
	mousepos = p;
	dword mm = 0;
	if((e & ACTION) == DOUBLE)
		mm |= K_MOUSEDOUBLE;
	if((e & ACTION) == TRIPLE)
		mm |= K_MOUSETRIPLE;
	
	if (bcaptureLock) return MouseEventH(e, p, zd, GetMouseFlags() | mm); ///mais...
		
	Rect view = GetView();
	if(mouseCtrl != this) {
        ...


[587]
Image Ctrl::DispatchMouseEvent(int e, Point p, int zd) {
	GuiLock __;
#if defined(flagWINGL) || defined(flagLINUXGL)
	if(!IsEnabled() && this != (Ctrl*) &infoPanel)
		return Image::Arrow();
#else
	if(!IsEnabled())
		return Image::Arrow();
#endif

	if(captureCtrl && captureCtrl->bcaptureLock) ///mais...
	{
		if (captureCtrl!=this) return captureCtrl->DispatchMouseEvent(e, p, zd);
		return captureCtrl->MEvent0(e, p, zd);
	}

	if(captureCtrl && captureCtrl != this && captureCtrl->IsMouseActive())
        ...


[618]
bool Ctrl::SetCapture(bool bLock) { ///mais...
	GuiLock __;
	ReleaseCtrlCapture();
	if(!GetTopCtrl()->SetWndCapture()) return false;
	captureCtrl = mouseCtrl = this;
	bcaptureLock=bLock; ///mais...
	return true;
}


[628]
bool Ctrl::ReleaseCapture(bool bUnlock) { ///mais...
	GuiLock __;
	if (bcaptureLock) bcaptureLock=!bUnlock; ///mais...
	return this == captureCtrl && ReleaseCtrlCapture();
}


[634]
bool Ctrl::ReleaseCtrlCapture() {
	GuiLock __;
	if (captureCtrl && captureCtrl->bcaptureLock) return false; ///mais...
	if(captureCtrl) {
		captureCtrl->CancelMode();
		Ctrl *w = captureCtrl->GetTopCtrl();
		captureCtrl = NULL;
		if(w->HasWndCapture()) {
			w->ReleaseWndCapture();
			return true;
		}
	}
	captureCtrl = NULL;
	return false;
}


All mouse events now goes to my control exclusively (for testing I use K_ESCAPE hotkey to release)

These changes 'should' not affect any other uses of the functions. - mirek, what say you?


I'm looking at 'XWarpPointer()' to force pointer to remain physically within my control's view-area
(don't know what MSWindows would require)

Adding test-code:

  • Attachment: main.cpp
    (Size: 2.14KB, Downloaded 219 times)

[Updated on: Fri, 20 January 2017 09:43]

Report message to a moderator

Re: capture mouse and limit all events to window [message #47486 is a reply to message #47441] Sun, 22 January 2017 13:02 Go to previous messageGo to next message
slashupp is currently offline  slashupp
Messages: 231
Registered: July 2009
Experienced Member

@mirek:

I made the above changes to my copy of upp-svn10672 and done make & make install
and is using the resultant theide without problem - there shouldn't be. (In these
changes I've replaced the phrase 'lock' with 'exclusive')

Would it be possible to make the changes part of the official source?

Re: capture mouse and limit all events to window [message #51704 is a reply to message #47441] Mon, 29 April 2019 09:16 Go to previous messageGo to next message
slashupp is currently offline  slashupp
Messages: 231
Registered: July 2009
Experienced Member
This applies to Linux-only.

To position the mouse-pointer anywhere in the window, or centered on a specific control in the window
I came up with this 'hack':

Header:
#ifndef _xfunc_h_
#define _xfunc_h_

#include <CtrlCore/CtrlCore.h>

namespace XFUNC
{
	
void set_Xmouse_pos(int x, int y);
void set_Xmouse_pos(Upp::Ctrl *pCtrl);

} //namespace XFUNC


#endif


Implementation:
#include "xfunc.h"

namespace XFUNC
{
	
#include <X11/Xlib.h>

void set_Xmouse_pos(int x, int y) //Ctrl *pCtrl)
{
	Upp::GuiLock __;
	static Display *disp=XOpenDisplay(0);
	if (disp)
	{
		Window wroot=XRootWindow(disp, 0);
		XWarpPointer(disp, 0, wroot, 0, 0, 0, 0, x, y);
		XFlush(disp);
	}
}

void set_Xmouse_pos(Upp::Ctrl *pCtrl)
{
	if (!pCtrl) return;
	Upp::GuiLock __;
	int x, y;
	Upp::Rect r=pCtrl->GetScreenRect();
	x=(r.left+r.Width()/2);
	y=(r.top+r.Height()/2);
	static Display *disp=XOpenDisplay(0);
	if (disp)
	{
		Window wroot=XRootWindow(disp, 0);
		XWarpPointer(disp, 0, wroot, 0, 0, 0, 0, x, y);
		XFlush(disp);
	}
}


} //namespace XFUNC


Hope this helps someone
Re: capture mouse and limit all events to window [message #52009 is a reply to message #51704] Thu, 04 July 2019 11:06 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
This should not be mixed with "capture" concept. It is already hard to make capture consistent across platforms (win/x11/macos) and this would add another level of complication.

What we need instead IMO is to encapsulate platform specific apis like warp.

Mirek
Previous Topic: Problem adapting child Ctrl to scroller example code
Next Topic: Problem with ScrollBar and multiple controls
Goto Forum:
  


Current Time: Thu Mar 28 21:46:54 CET 2024

Total time taken to generate the page: 0.00783 seconds