Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
e03b8e1a
Commit
e03b8e1a
authored
Oct 01, 2012
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11: Use ARGB layered windows for system tray icons when supported.
parent
d8247efd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
138 additions
and
17 deletions
+138
-17
systray.c
dlls/winex11.drv/systray.c
+132
-8
window.c
dlls/winex11.drv/window.c
+3
-8
x11drv.h
dlls/winex11.drv/x11drv.h
+2
-1
x11drv_main.c
dlls/winex11.drv/x11drv_main.c
+1
-0
No files found.
dlls/winex11.drv/systray.c
View file @
e03b8e1a
...
...
@@ -53,6 +53,7 @@ struct tray_icon
HICON
image
;
/* the image to render */
HWND
owner
;
/* the HWND passed in to the Shell_NotifyIcon call */
HWND
window
;
/* the adaptor window */
BOOL
layered
;
/* whether we are using a layered window */
HWND
tooltip
;
/* Icon tooltip */
UINT
state
;
/* state flags */
UINT
id
;
/* the unique id given by the app */
...
...
@@ -361,6 +362,80 @@ static void remove_from_standalone_tray( struct tray_icon *icon )
TRACE
(
"removed %u now %d icons
\n
"
,
icon
->
id
,
nb_displayed
);
}
static
void
repaint_tray_icon
(
struct
tray_icon
*
icon
)
{
BLENDFUNCTION
blend
=
{
AC_SRC_OVER
,
0
,
255
,
AC_SRC_ALPHA
};
int
width
=
GetSystemMetrics
(
SM_CXSMICON
);
int
height
=
GetSystemMetrics
(
SM_CYSMICON
);
BITMAPINFO
*
info
;
HBITMAP
dib
,
mask
;
HDC
hdc
;
RECT
rc
;
SIZE
size
;
POINT
pos
;
int
i
,
x
,
y
;
void
*
color_bits
,
*
mask_bits
;
DWORD
*
ptr
;
BOOL
has_alpha
=
FALSE
;
GetWindowRect
(
icon
->
window
,
&
rc
);
size
.
cx
=
rc
.
right
-
rc
.
left
;
size
.
cy
=
rc
.
bottom
-
rc
.
top
;
pos
.
x
=
(
size
.
cx
-
width
)
/
2
;
pos
.
y
=
(
size
.
cy
-
height
)
/
2
;
info
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
FIELD_OFFSET
(
BITMAPINFO
,
bmiColors
[
2
]
));
if
(
!
info
)
return
;
info
->
bmiHeader
.
biSize
=
sizeof
(
info
->
bmiHeader
);
info
->
bmiHeader
.
biWidth
=
size
.
cx
;
info
->
bmiHeader
.
biHeight
=
size
.
cy
;
info
->
bmiHeader
.
biBitCount
=
32
;
info
->
bmiHeader
.
biPlanes
=
1
;
info
->
bmiHeader
.
biCompression
=
BI_RGB
;
hdc
=
CreateCompatibleDC
(
0
);
if
(
!
(
dib
=
CreateDIBSection
(
0
,
info
,
DIB_RGB_COLORS
,
&
color_bits
,
NULL
,
0
)))
goto
done
;
SelectObject
(
hdc
,
dib
);
DrawIconEx
(
hdc
,
pos
.
x
,
pos
.
y
,
icon
->
image
,
width
,
height
,
0
,
0
,
DI_DEFAULTSIZE
|
DI_NORMAL
);
/* check if the icon was drawn with an alpha channel */
for
(
i
=
0
,
ptr
=
color_bits
;
i
<
size
.
cx
*
size
.
cy
;
i
++
)
if
((
has_alpha
=
(
ptr
[
i
]
&
0xff000000
)
!=
0
))
break
;
if
(
!
has_alpha
)
{
unsigned
int
width_bytes
=
(
size
.
cx
+
31
)
/
32
*
4
;
info
->
bmiHeader
.
biBitCount
=
1
;
info
->
bmiColors
[
0
].
rgbRed
=
0
;
info
->
bmiColors
[
0
].
rgbGreen
=
0
;
info
->
bmiColors
[
0
].
rgbBlue
=
0
;
info
->
bmiColors
[
0
].
rgbReserved
=
0
;
info
->
bmiColors
[
1
].
rgbRed
=
0xff
;
info
->
bmiColors
[
1
].
rgbGreen
=
0xff
;
info
->
bmiColors
[
1
].
rgbBlue
=
0xff
;
info
->
bmiColors
[
1
].
rgbReserved
=
0
;
if
(
!
(
mask
=
CreateDIBSection
(
0
,
info
,
DIB_RGB_COLORS
,
&
mask_bits
,
NULL
,
0
)))
goto
done
;
memset
(
mask_bits
,
0xff
,
width_bytes
*
size
.
cy
);
SelectObject
(
hdc
,
mask
);
DrawIconEx
(
hdc
,
pos
.
x
,
pos
.
y
,
icon
->
image
,
width
,
height
,
0
,
0
,
DI_DEFAULTSIZE
|
DI_MASK
);
for
(
y
=
0
,
ptr
=
color_bits
;
y
<
size
.
cy
;
y
++
)
for
(
x
=
0
;
x
<
size
.
cx
;
x
++
,
ptr
++
)
if
(
!
((((
BYTE
*
)
mask_bits
)[
y
*
width_bytes
+
x
/
8
]
<<
(
x
%
8
))
&
0x80
))
*
ptr
|=
0xff000000
;
SelectObject
(
hdc
,
dib
);
DeleteObject
(
mask
);
}
UpdateLayeredWindow
(
icon
->
window
,
0
,
NULL
,
NULL
,
hdc
,
NULL
,
0
,
&
blend
,
ULW_ALPHA
);
done:
if
(
hdc
)
DeleteDC
(
hdc
);
if
(
dib
)
DeleteObject
(
dib
);
}
/* window procedure for the individual tray icon window */
static
LRESULT
WINAPI
tray_icon_wndproc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
...
...
@@ -381,6 +456,10 @@ static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
SetTimer
(
hwnd
,
VALID_WIN_TIMER
,
VALID_WIN_TIMEOUT
,
NULL
);
break
;
case
WM_SIZE
:
if
(
icon
->
window
&&
icon
->
layered
)
repaint_tray_icon
(
icon
);
break
;
case
WM_PAINT
:
{
PAINTSTRUCT
ps
;
...
...
@@ -455,6 +534,33 @@ static Window get_systray_selection_owner( Display *display )
return
XGetSelectionOwner
(
display
,
systray_atom
);
}
static
void
get_systray_visual_info
(
Display
*
display
,
Window
systray_window
,
XVisualInfo
*
info
)
{
XVisualInfo
*
list
,
template
;
VisualID
*
visual_id
;
Atom
type
;
int
format
,
num
;
unsigned
long
count
,
remaining
;
*
info
=
default_visual
;
if
(
XGetWindowProperty
(
display
,
systray_window
,
x11drv_atom
(
_NET_SYSTEM_TRAY_VISUAL
),
0
,
65536
/
sizeof
(
CARD32
),
False
,
XA_VISUALID
,
&
type
,
&
format
,
&
count
,
&
remaining
,
(
unsigned
char
**
)
&
visual_id
))
return
;
if
(
type
==
XA_VISUALID
&&
format
==
32
)
{
template
.
visualid
=
visual_id
[
0
];
if
((
list
=
XGetVisualInfo
(
display
,
VisualIDMask
,
&
template
,
&
num
)))
{
*
info
=
list
[
0
];
TRACE
(
"systray window %lx got visual %lx
\n
"
,
systray_window
,
info
->
visualid
);
XFree
(
list
);
}
}
XFree
(
visual_id
);
}
static
BOOL
init_systray
(
void
)
{
static
BOOL
init_done
;
...
...
@@ -513,15 +619,26 @@ static void dock_systray_icon( Display *display, struct tray_icon *icon, Window
Window
window
;
XEvent
ev
;
XSetWindowAttributes
attr
;
XVisualInfo
visual
;
struct
x11drv_win_data
*
data
;
get_systray_visual_info
(
display
,
systray_window
,
&
visual
);
icon
->
layered
=
(
visual
.
visualid
!=
default_visual
.
visualid
);
icon
->
window
=
CreateWindowExW
(
icon
->
layered
?
WS_EX_LAYERED
:
0
,
icon_classname
,
NULL
,
WS_CLIPSIBLINGS
|
WS_POPUP
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
icon_cx
,
icon_cy
,
NULL
,
NULL
,
NULL
,
icon
);
if
(
!
(
data
=
get_win_data
(
icon
->
window
)))
return
;
if
(
icon
->
layered
)
set_window_visual
(
data
,
&
visual
);
make_window_embedded
(
data
);
window
=
data
->
whole_window
;
release_win_data
(
data
);
icon
->
window
=
CreateWindowW
(
icon_classname
,
NULL
,
WS_CLIPSIBLINGS
|
WS_POPUP
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
icon_cx
,
icon_cy
,
NULL
,
NULL
,
NULL
,
icon
);
make_window_embedded
(
icon
->
window
);
create_tooltip
(
icon
);
ShowWindow
(
icon
->
window
,
SW_SHOWNA
);
if
(
!
(
window
=
X11DRV_get_whole_window
(
icon
->
window
)))
return
;
TRACE
(
"icon window %p/%lx
\n
"
,
icon
->
window
,
window
);
/* send the docking request message */
...
...
@@ -535,9 +652,14 @@ static void dock_systray_icon( Display *display, struct tray_icon *icon, Window
ev
.
xclient
.
data
.
l
[
3
]
=
0
;
ev
.
xclient
.
data
.
l
[
4
]
=
0
;
XSendEvent
(
display
,
systray_window
,
False
,
NoEventMask
,
&
ev
);
attr
.
background_pixmap
=
ParentRelative
;
attr
.
bit_gravity
=
ForgetGravity
;
XChangeWindowAttributes
(
display
,
window
,
CWBackPixmap
|
CWBitGravity
,
&
attr
);
if
(
!
icon
->
layered
)
{
attr
.
background_pixmap
=
ParentRelative
;
attr
.
bit_gravity
=
ForgetGravity
;
XChangeWindowAttributes
(
display
,
window
,
CWBackPixmap
|
CWBitGravity
,
&
attr
);
}
else
repaint_tray_icon
(
icon
);
}
/* dock systray windows again with the new owner */
...
...
@@ -572,6 +694,7 @@ static BOOL hide_icon( struct tray_icon *icon )
DestroyWindow
(
icon
->
window
);
DestroyWindow
(
icon
->
tooltip
);
icon
->
window
=
0
;
icon
->
layered
=
FALSE
;
icon
->
tooltip
=
0
;
remove_from_standalone_tray
(
icon
);
update_balloon
(
icon
);
...
...
@@ -614,6 +737,7 @@ static BOOL modify_icon( struct tray_icon *icon, NOTIFYICONDATAW *nid )
if
(
icon
->
window
)
{
if
(
icon
->
display
!=
-
1
)
InvalidateRect
(
icon
->
window
,
NULL
,
TRUE
);
else
if
(
icon
->
layered
)
repaint_tray_icon
(
icon
);
else
{
Window
win
=
X11DRV_get_whole_window
(
icon
->
window
);
...
...
dlls/winex11.drv/window.c
View file @
e03b8e1a
...
...
@@ -1124,12 +1124,8 @@ static void unmap_window( HWND hwnd )
/***********************************************************************
* make_window_embedded
*/
void
make_window_embedded
(
HWND
hwnd
)
void
make_window_embedded
(
struct
x11drv_win_data
*
data
)
{
struct
x11drv_win_data
*
data
=
get_win_data
(
hwnd
);
if
(
!
data
)
return
;
/* the window cannot be mapped before being embedded */
if
(
data
->
mapped
)
{
...
...
@@ -1139,10 +1135,9 @@ void make_window_embedded( HWND hwnd )
}
data
->
embedded
=
TRUE
;
data
->
managed
=
TRUE
;
SetPropA
(
hwnd
,
managed_prop
,
(
HANDLE
)
1
);
SetPropA
(
data
->
hwnd
,
managed_prop
,
(
HANDLE
)
1
);
sync_window_style
(
data
);
set_xembed_flags
(
data
,
data
->
mapped
?
XEMBED_MAPPED
:
0
);
release_win_data
(
data
);
}
...
...
@@ -2376,7 +2371,7 @@ BOOL CDECL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO
if
(
!
(
data
=
get_win_data
(
hwnd
)))
return
FALSE
;
set_window_visual
(
data
,
&
argb_visual
);
if
(
!
data
->
embedded
)
set_window_visual
(
data
,
&
argb_visual
);
rect
=
*
window_rect
;
OffsetRect
(
&
rect
,
-
window_rect
->
left
,
-
window_rect
->
top
);
...
...
dlls/winex11.drv/x11drv.h
View file @
e03b8e1a
...
...
@@ -407,6 +407,7 @@ enum x11drv_atoms
XATOM__NET_SUPPORTED
,
XATOM__NET_SYSTEM_TRAY_OPCODE
,
XATOM__NET_SYSTEM_TRAY_S0
,
XATOM__NET_SYSTEM_TRAY_VISUAL
,
XATOM__NET_WM_ICON
,
XATOM__NET_WM_MOVERESIZE
,
XATOM__NET_WM_NAME
,
...
...
@@ -570,7 +571,7 @@ extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ) DECLSPEC_HIDDEN;
extern
Window
init_clip_window
(
void
)
DECLSPEC_HIDDEN
;
extern
void
update_user_time
(
Time
time
)
DECLSPEC_HIDDEN
;
extern
void
update_net_wm_states
(
struct
x11drv_win_data
*
data
)
DECLSPEC_HIDDEN
;
extern
void
make_window_embedded
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
void
make_window_embedded
(
struct
x11drv_win_data
*
data
)
DECLSPEC_HIDDEN
;
extern
void
set_window_visual
(
struct
x11drv_win_data
*
data
,
const
XVisualInfo
*
vis
)
DECLSPEC_HIDDEN
;
extern
void
change_systray_owner
(
Display
*
display
,
Window
systray_window
)
DECLSPEC_HIDDEN
;
extern
void
update_systray_balloon_position
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/winex11.drv/x11drv_main.c
View file @
e03b8e1a
...
...
@@ -134,6 +134,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"_NET_SUPPORTED"
,
"_NET_SYSTEM_TRAY_OPCODE"
,
"_NET_SYSTEM_TRAY_S0"
,
"_NET_SYSTEM_TRAY_VISUAL"
,
"_NET_WM_ICON"
,
"_NET_WM_MOVERESIZE"
,
"_NET_WM_NAME"
,
...
...
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