2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include "CaptureWindow.h"
17 static const bigtime_t kUpdateDelay
= 50000;
21 class CaptureView
: public BView
{
24 virtual ~CaptureView();
26 void AddMoveOutNotification(BMessage
* message
);
28 virtual void MouseMoved(BPoint point
, uint32 transit
,
29 const BMessage
* dragMessage
);
30 virtual void KeyDown(const char* bytes
, int32 numBytes
);
33 void _UpdateLast(const BPoint
& point
);
34 void _Notify(uint32 location
, team_id team
);
35 void _SendMovedOutNotification();
37 static team_id
_CurrentTeam();
46 BMessenger fMovedOutMessenger
;
51 CaptureView::CaptureView()
54 fModifierMask(B_CONTROL_KEY
),
57 SetEventMask(B_POINTER_EVENTS
| B_KEYBOARD_EVENTS
, B_NO_POINTER_HISTORY
);
58 _UpdateLast(BPoint(-1, -1));
62 CaptureView::~CaptureView()
68 CaptureView::AddMoveOutNotification(BMessage
* message
)
70 if (fMovedOutWhat
!= 0)
71 _SendMovedOutNotification();
73 if (message
->FindMessenger("target", &fMovedOutMessenger
) == B_OK
74 && message
->FindRect("frame", &fMovedOutFrame
) == B_OK
)
75 fMovedOutWhat
= (uint32
)message
->FindInt32("what");
80 CaptureView::MouseMoved(BPoint point
, uint32 transit
,
81 const BMessage
* dragMessage
)
83 ConvertToScreen(&point
);
85 if (fMovedOutWhat
!= 0 && !fMovedOutFrame
.Contains(point
))
86 _SendMovedOutNotification();
88 uint32 modifiers
= ::modifiers();
89 if ((modifiers
& fModifierMask
) == 0) {
94 // TODO: we will need to iterate over all existing screens to find the
97 BRect screenFrame
= screen
.Frame();
99 uint32 location
= kNowhere
;
100 if (point
.x
<= screenFrame
.left
&& fLastPoint
.x
> screenFrame
.left
)
101 location
= kLeftEdge
;
102 else if (point
.x
>= screenFrame
.right
&& fLastPoint
.x
< screenFrame
.right
)
103 location
= kRightEdge
;
104 else if (point
.y
<= screenFrame
.top
&& fLastPoint
.y
> screenFrame
.top
)
106 else if (point
.y
>= screenFrame
.bottom
&& fLastPoint
.y
< screenFrame
.bottom
)
107 location
= kBottomEdge
;
109 if (location
!= kNowhere
)
110 _Notify(location
, fLastTeam
);
117 CaptureView::KeyDown(const char* bytes
, int32 numBytes
)
119 if ((::modifiers() & (B_CONTROL_KEY
| B_SHIFT_KEY
| B_OPTION_KEY
120 | B_COMMAND_KEY
)) != (B_COMMAND_KEY
| B_CONTROL_KEY
))
123 uint32 location
= kNowhere
;
127 location
= kLeftEdge
;
130 location
= kRightEdge
;
136 location
= kBottomEdge
;
140 if (location
!= kNowhere
)
141 _Notify(location
, _CurrentTeam());
146 CaptureView::_UpdateLast(const BPoint
& point
)
150 bigtime_t now
= system_time();
152 // We update the currently active application only, if the mouse did
153 // not move over it for a certain time - this is necessary only for
154 // focus follow mouse.
155 if (now
> fLastEvent
+ kUpdateDelay
)
156 fLastTeam
= _CurrentTeam();
163 CaptureView::_Notify(uint32 location
, team_id team
)
165 if (location
== kNowhere
)
168 BMessage
message(kMsgLocationTrigger
);
169 message
.AddInt32("location", location
);
170 message
.AddInt32("team", team
);
172 be_app
->PostMessage(&message
);
177 CaptureView::_SendMovedOutNotification()
179 BMessage
movedOut(fMovedOutWhat
);
180 fMovedOutMessenger
.SendMessage(&movedOut
);
186 CaptureView::_CurrentTeam()
189 status_t status
= be_roster
->GetActiveAppInfo(&appInfo
);
200 CaptureWindow::CaptureWindow()
202 BWindow(BRect(0, 0, 100, 100), "mouse capture", B_NO_BORDER_WINDOW_LOOK
,
203 B_NORMAL_WINDOW_FEEL
, B_ASYNCHRONOUS_CONTROLS
, B_ALL_WORKSPACES
)
205 fCaptureView
= new CaptureView();
206 AddChild(fCaptureView
);
210 CaptureWindow::~CaptureWindow()
216 CaptureWindow::MessageReceived(BMessage
* message
)
218 switch (message
->what
) {
219 case kMsgHideWhenMouseMovedOut
:
220 fCaptureView
->AddMoveOutNotification(message
);
223 BWindow::MessageReceived(message
);