Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
7ed00f6d
Commit
7ed00f6d
authored
Sep 05, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Sep 06, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Add support for mouse-move and right- and middle-click events on…
winemac: Add support for mouse-move and right- and middle-click events on systray icons in the Mac status bar.
parent
ee771fdd
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
186 additions
and
45 deletions
+186
-45
cocoa_status_item.m
dlls/winemac.drv/cocoa_status_item.m
+119
-17
event.c
dlls/winemac.drv/event.c
+9
-4
macdrv.h
dlls/winemac.drv/macdrv.h
+2
-1
macdrv_cocoa.h
dlls/winemac.drv/macdrv_cocoa.h
+8
-2
systray.c
dlls/winemac.drv/systray.c
+48
-21
No files found.
dlls/winemac.drv/cocoa_status_item.m
View file @
7ed00f6d
...
...
@@ -24,34 +24,44 @@
#import "cocoa_event.h"
@interface
WineStatusItem
:
NS
Object
@interface
WineStatusItem
:
NS
View
{
NSStatusItem
*
item
;
WineEventQueue
*
queue
;
NSTrackingArea
*
trackingArea
;
NSImage
*
image
;
}
@property
(
retain
,
nonatomic
)
NSStatusItem
*
item
;
@property
(
assign
,
nonatomic
)
WineEventQueue
*
queue
;
@property
(
retain
,
nonatomic
)
NSImage
*
image
;
@end
@implementation
WineStatusItem
@synthesize
item
,
queue
;
@synthesize
item
,
queue
,
image
;
-
(
id
)
initWithEventQueue
:(
WineEventQueue
*
)
inQueue
{
self
=
[
super
init
];
NSStatusBar
*
statusBar
=
[
NSStatusBar
systemStatusBar
];
CGFloat
thickness
=
[
statusBar
thickness
];
self
=
[
super
initWithFrame
:
NSMakeRect
(
0
,
0
,
thickness
,
thickness
)];
if
(
self
)
{
NSStatusBar
*
statusBar
=
[
NSStatusBar
systemStatusBar
];
item
=
[[
statusBar
statusItemWithLength
:
NSSquareStatusItemLength
]
retain
];
[
item
setTarget
:
self
];
[
item
setAction
:
@selector
(
clicked
:)];
[
item
setDoubleAction
:
@selector
(
doubleClicked
:)];
// This is a retain cycle which is broken in -removeFromStatusBar.
[
item
setView
:
self
];
queue
=
inQueue
;
trackingArea
=
[[
NSTrackingArea
alloc
]
initWithRect
:[
self
bounds
]
options
:
NSTrackingMouseMoved
|
NSTrackingActiveAlways
|
NSTrackingInVisibleRect
owner:
self
userInfo:
nil
];
[
self
addTrackingArea
:
trackingArea
];
}
return
self
;
}
...
...
@@ -64,37 +74,129 @@
[
statusBar
removeStatusItem
:
item
];
[
item
release
];
}
[
image
release
];
[
trackingArea
release
];
[
super
dealloc
];
}
-
(
void
)
setImage
:
(
NSImage
*
)
inImage
{
if
(
image
!=
inImage
)
{
[
image
release
];
image
=
[
inImage
retain
];
[
self
setNeedsDisplay
:
YES
];
}
}
-
(
void
)
removeFromStatusBar
{
if
(
item
)
{
NSStatusBar
*
statusBar
=
[
NSStatusBar
systemStatusBar
];
[
statusBar
removeStatusItem
:
item
];
[
item
setView
:
nil
];
self
.
item
=
nil
;
}
}
-
(
void
)
post
ClickedEventWithCount
:
(
int
)
count
-
(
void
)
post
MouseButtonEvent
:
(
NSEvent
*
)
nsevent
;
{
macdrv_event
*
event
;
event
=
macdrv_create_event
(
STATUS_ITEM_CLICKED
,
nil
);
event
->
status_item_clicked
.
item
=
(
macdrv_status_item
)
self
;
event
->
status_item_clicked
.
count
=
count
;
NSUInteger
typeMask
=
NSEventMaskFromType
([
nsevent
type
]);
event
=
macdrv_create_event
(
STATUS_ITEM_MOUSE_BUTTON
,
nil
);
event
->
status_item_mouse_button
.
item
=
(
macdrv_status_item
)
self
;
event
->
status_item_mouse_button
.
button
=
[
nsevent
buttonNumber
];
event
->
status_item_mouse_button
.
down
=
(
typeMask
&
(
NSLeftMouseDownMask
|
NSRightMouseDownMask
|
NSOtherMouseDownMask
))
!=
0
;
event
->
status_item_mouse_button
.
count
=
[
nsevent
clickCount
];
[
queue
postEvent
:
event
];
macdrv_release_event
(
event
);
}
-
(
void
)
clicked
:
(
id
)
sender
/*
* ---------- NSView methods ----------
*/
-
(
void
)
drawRect
:
(
NSRect
)
rect
{
[
item
drawStatusBarBackgroundInRect
:[
self
bounds
]
withHighlight
:
NO
];
if
(
image
)
{
NSSize
imageSize
=
[
image
size
];
NSRect
bounds
=
[
self
bounds
];
NSPoint
imageOrigin
=
NSMakePoint
(
NSMidX
(
bounds
)
-
imageSize
.
width
/
2
,
NSMidY
(
bounds
)
-
imageSize
.
height
/
2
);
imageOrigin
=
[
self
convertPointToBase
:
imageOrigin
];
imageOrigin
.
x
=
floor
(
imageOrigin
.
x
);
imageOrigin
.
y
=
floor
(
imageOrigin
.
y
);
imageOrigin
=
[
self
convertPointFromBase
:
imageOrigin
];
[
image
drawAtPoint
:
imageOrigin
fromRect
:
NSZeroRect
operation
:
NSCompositeSourceOver
fraction
:
1
];
}
}
/*
* ---------- NSResponder methods ----------
*/
-
(
void
)
mouseDown
:
(
NSEvent
*
)
event
{
[
self
postMouseButtonEvent
:
event
];
}
-
(
void
)
mouseDragged
:
(
NSEvent
*
)
event
{
[
self
mouseMoved
:
event
];
}
-
(
void
)
mouseMoved
:
(
NSEvent
*
)
nsevent
{
macdrv_event
*
event
;
event
=
macdrv_create_event
(
STATUS_ITEM_MOUSE_MOVE
,
nil
);
event
->
status_item_mouse_move
.
item
=
(
macdrv_status_item
)
self
;
[
queue
postEvent
:
event
];
macdrv_release_event
(
event
);
}
-
(
void
)
mouseUp
:
(
NSEvent
*
)
event
{
[
self
postMouseButtonEvent
:
event
];
}
-
(
void
)
otherMouseDown
:
(
NSEvent
*
)
event
{
[
self
postMouseButtonEvent
:
event
];
}
-
(
void
)
otherMouseDragged
:
(
NSEvent
*
)
event
{
[
self
mouseMoved
:
event
];
}
-
(
void
)
otherMouseUp
:
(
NSEvent
*
)
event
{
[
self
postMouseButtonEvent
:
event
];
}
-
(
void
)
rightMouseDown
:
(
NSEvent
*
)
event
{
[
self
postMouseButtonEvent
:
event
];
}
-
(
void
)
rightMouseDragged
:
(
NSEvent
*
)
event
{
[
self
postClickedEventWithCount
:
1
];
[
self
mouseMoved
:
event
];
}
-
(
void
)
doubleClicked
:
(
id
)
sender
-
(
void
)
rightMouseUp
:
(
NSEvent
*
)
event
{
[
self
post
ClickedEventWithCount
:
2
];
[
self
post
MouseButtonEvent
:
event
];
}
@end
...
...
@@ -165,7 +267,7 @@ void macdrv_set_status_item_image(macdrv_status_item s, CGImageRef cgimage)
if
(
changed
)
[
image
setSize
:
size
];
}
[
statusItem
.
item
setImage
:
image
]
;
statusItem
.
image
=
image
;
[
image
release
];
});
}
...
...
@@ -183,6 +285,6 @@ void macdrv_set_status_item_tooltip(macdrv_status_item s, CFStringRef cftip)
if
(
!
[
tip
length
])
tip
=
nil
;
OnMainThreadAsync
(
^
{
[
statusItem
.
item
setToolTip
:
tip
];
[
statusItem
setToolTip
:
tip
];
});
}
dlls/winemac.drv/event.c
View file @
7ed00f6d
...
...
@@ -45,7 +45,8 @@ static const char *dbgstr_event(int type)
"MOUSE_SCROLL"
,
"QUERY_EVENT"
,
"RELEASE_CAPTURE"
,
"STATUS_ITEM_CLICKED"
,
"STATUS_ITEM_MOUSE_BUTTON"
,
"STATUS_ITEM_MOUSE_MOVE"
,
"WINDOW_CLOSE_REQUESTED"
,
"WINDOW_DID_MINIMIZE"
,
"WINDOW_DID_UNMINIMIZE"
,
...
...
@@ -93,7 +94,8 @@ static macdrv_event_mask get_event_mask(DWORD mask)
event_mask
|=
event_mask_for_type
(
APP_QUIT_REQUESTED
);
event_mask
|=
event_mask_for_type
(
DISPLAYS_CHANGED
);
event_mask
|=
event_mask_for_type
(
IM_SET_TEXT
);
event_mask
|=
event_mask_for_type
(
STATUS_ITEM_CLICKED
);
event_mask
|=
event_mask_for_type
(
STATUS_ITEM_MOUSE_BUTTON
);
event_mask
|=
event_mask_for_type
(
STATUS_ITEM_MOUSE_MOVE
);
event_mask
|=
event_mask_for_type
(
WINDOW_CLOSE_REQUESTED
);
event_mask
|=
event_mask_for_type
(
WINDOW_DID_MINIMIZE
);
event_mask
|=
event_mask_for_type
(
WINDOW_DID_UNMINIMIZE
);
...
...
@@ -207,8 +209,11 @@ void macdrv_handle_event(const macdrv_event *event)
case
RELEASE_CAPTURE
:
macdrv_release_capture
(
hwnd
,
event
);
break
;
case
STATUS_ITEM_CLICKED
:
macdrv_status_item_clicked
(
event
);
case
STATUS_ITEM_MOUSE_BUTTON
:
macdrv_status_item_mouse_button
(
event
);
break
;
case
STATUS_ITEM_MOUSE_MOVE
:
macdrv_status_item_mouse_move
(
event
);
break
;
case
WINDOW_CLOSE_REQUESTED
:
macdrv_window_close_requested
(
hwnd
);
...
...
dlls/winemac.drv/macdrv.h
View file @
7ed00f6d
...
...
@@ -195,7 +195,8 @@ extern CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP
extern
CGImageRef
create_cgimage_from_icon
(
HANDLE
icon
,
int
width
,
int
height
)
DECLSPEC_HIDDEN
;
extern
CFArrayRef
create_app_icon_images
(
void
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_status_item_clicked
(
const
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_status_item_mouse_button
(
const
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_status_item_mouse_move
(
const
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
/**************************************************************************
...
...
dlls/winemac.drv/macdrv_cocoa.h
View file @
7ed00f6d
...
...
@@ -176,7 +176,8 @@ enum {
MOUSE_SCROLL
,
QUERY_EVENT
,
RELEASE_CAPTURE
,
STATUS_ITEM_CLICKED
,
STATUS_ITEM_MOUSE_BUTTON
,
STATUS_ITEM_MOUSE_MOVE
,
WINDOW_CLOSE_REQUESTED
,
WINDOW_DID_MINIMIZE
,
WINDOW_DID_UNMINIMIZE
,
...
...
@@ -248,8 +249,13 @@ typedef struct macdrv_event {
}
query_event
;
struct
{
macdrv_status_item
item
;
int
button
;
int
down
;
int
count
;
}
status_item_clicked
;
}
status_item_mouse_button
;
struct
{
macdrv_status_item
item
;
}
status_item_mouse_move
;
struct
{
CGRect
frame
;
}
window_frame_changed
;
...
...
dlls/winemac.drv/systray.c
View file @
7ed00f6d
...
...
@@ -308,22 +308,38 @@ int CDECL wine_notify_icon(DWORD msg, NOTIFYICONDATAW *data)
/***********************************************************************
* macdrv_status_item_
clicked
* macdrv_status_item_
mouse_button
*
* Handle STATUS_ITEM_
CLICKED
events.
* Handle STATUS_ITEM_
MOUSE_BUTTON
events.
*/
void
macdrv_status_item_
clicked
(
const
macdrv_event
*
event
)
void
macdrv_status_item_
mouse_button
(
const
macdrv_event
*
event
)
{
struct
tray_icon
*
icon
;
TRACE
(
"item %p count %d
\n
"
,
event
->
status_item_clicked
.
item
,
event
->
status_item_clicked
.
count
);
TRACE
(
"item %p button %d down %d count %d
\n
"
,
event
->
status_item_mouse_button
.
item
,
event
->
status_item_mouse_button
.
button
,
event
->
status_item_mouse_button
.
down
,
event
->
status_item_mouse_button
.
count
);
LIST_FOR_EACH_ENTRY
(
icon
,
&
icon_list
,
struct
tray_icon
,
entry
)
{
if
(
icon
->
status_item
==
event
->
status_item_
clicked
.
item
)
if
(
icon
->
status_item
==
event
->
status_item_
mouse_button
.
item
)
{
UINT
down
;
UINT
msg
;
switch
(
event
->
status_item_mouse_button
.
button
)
{
case
0
:
msg
=
WM_LBUTTONDOWN
;
break
;
case
1
:
msg
=
WM_RBUTTONDOWN
;
break
;
case
2
:
msg
=
WM_MBUTTONDOWN
;
break
;
default:
TRACE
(
"ignoring button beyond the third
\n
"
);
return
;
}
if
(
!
event
->
status_item_mouse_button
.
down
)
msg
+=
WM_LBUTTONUP
-
WM_LBUTTONDOWN
;
else
if
(
event
->
status_item_mouse_button
.
count
%
2
==
0
)
msg
+=
WM_LBUTTONDBLCLK
-
WM_LBUTTONDOWN
;
if
(
!
SendMessageW
(
icon
->
owner
,
WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS
,
0
,
0
)
&&
GetLastError
()
==
ERROR_INVALID_WINDOW_HANDLE
)
...
...
@@ -333,18 +349,8 @@ void macdrv_status_item_clicked(const macdrv_event *event)
return
;
}
if
(
event
->
status_item_clicked
.
count
==
1
)
{
down
=
WM_LBUTTONDOWN
;
TRACE
(
"posting WM_LBUTTONDOWN to hwnd %p id 0x%x
\n
"
,
icon
->
owner
,
icon
->
id
);
}
else
{
down
=
WM_LBUTTONDBLCLK
;
TRACE
(
"posting WM_LBUTTONDBLCLK to hwnd %p id 0x%x
\n
"
,
icon
->
owner
,
icon
->
id
);
}
if
(
!
PostMessageW
(
icon
->
owner
,
icon
->
callback_message
,
icon
->
id
,
down
)
&&
TRACE
(
"posting msg 0x%04x to hwnd %p id 0x%x
\n
"
,
msg
,
icon
->
owner
,
icon
->
id
);
if
(
!
PostMessageW
(
icon
->
owner
,
icon
->
callback_message
,
icon
->
id
,
msg
)
&&
GetLastError
()
==
ERROR_INVALID_WINDOW_HANDLE
)
{
WARN
(
"window %p was destroyed, removing icon 0x%x
\n
"
,
icon
->
owner
,
icon
->
id
);
...
...
@@ -352,12 +358,33 @@ void macdrv_status_item_clicked(const macdrv_event *event)
return
;
}
TRACE
(
"posting WM_LBUTTONUP to hwnd %p id 0x%x
\n
"
,
icon
->
owner
,
icon
->
id
);
if
(
!
PostMessageW
(
icon
->
owner
,
icon
->
callback_message
,
icon
->
id
,
WM_LBUTTONUP
)
&&
break
;
}
}
}
/***********************************************************************
* macdrv_status_item_mouse_move
*
* Handle STATUS_ITEM_MOUSE_MOVE events.
*/
void
macdrv_status_item_mouse_move
(
const
macdrv_event
*
event
)
{
struct
tray_icon
*
icon
;
TRACE
(
"item %p
\n
"
,
event
->
status_item_mouse_move
.
item
);
LIST_FOR_EACH_ENTRY
(
icon
,
&
icon_list
,
struct
tray_icon
,
entry
)
{
if
(
icon
->
status_item
==
event
->
status_item_mouse_move
.
item
)
{
if
(
!
PostMessageW
(
icon
->
owner
,
icon
->
callback_message
,
icon
->
id
,
WM_MOUSEMOVE
)
&&
GetLastError
()
==
ERROR_INVALID_WINDOW_HANDLE
)
{
WARN
(
"window %p was destroyed, removing icon 0x%x
\n
"
,
icon
->
owner
,
icon
->
id
);
delete_icon
(
icon
);
return
;
}
break
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment