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
ace20fae
Commit
ace20fae
authored
Dec 15, 2010
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11: Add support for displaying system tray notification balloons.
parent
ab60be7b
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
144 additions
and
23 deletions
+144
-23
systray.c
dlls/winex11.drv/systray.c
+144
-23
No files found.
dlls/winex11.drv/systray.c
View file @
ace20fae
...
...
@@ -84,9 +84,19 @@ Atom systray_atom = 0;
#define MIN_DISPLAYED 8
#define ICON_BORDER 2
#define VALID_WIN_TIMER 1
#define BALLOON_CREATE_TIMER 2
#define BALLOON_SHOW_TIMER 3
#define VALID_WIN_TIMEOUT 2000
#define BALLOON_CREATE_TIMEOUT 2000
#define BALLOON_SHOW_MIN_TIMEOUT 10000
#define BALLOON_SHOW_MAX_TIMEOUT 30000
static
struct
tray_icon
*
balloon_icon
;
static
HWND
balloon_window
;
static
POINT
balloon_pos
;
/* stand-alone tray window */
static
HWND
standalone_tray
;
static
int
icon_cx
,
icon_cy
;
...
...
@@ -102,12 +112,11 @@ static struct tray_icon *get_icon(HWND owner, UINT id)
return
NULL
;
}
/* create tooltip window for icon */
static
void
create_tooltip
(
struct
tray_icon
*
icon
)
static
void
init_common_controls
(
void
)
{
static
BOOL
tooltips_
initialized
=
FALSE
;
static
BOOL
initialized
=
FALSE
;
if
(
!
tooltips_
initialized
)
if
(
!
initialized
)
{
INITCOMMONCONTROLSEX
init_tooltip
;
...
...
@@ -115,24 +124,19 @@ static void create_tooltip(struct tray_icon *icon)
init_tooltip
.
dwICC
=
ICC_TAB_CLASSES
;
InitCommonControlsEx
(
&
init_tooltip
);
tooltips_initialized
=
TRUE
;
}
if
(
icon
->
info_title
[
0
]
!=
0
)
{
icon
->
tooltip
=
CreateWindowExW
(
WS_EX_TOPMOST
,
TOOLTIPS_CLASSW
,
NULL
,
WS_POPUP
|
TTS_ALWAYSTIP
|
TTS_BALLOON
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
icon
->
window
,
NULL
,
NULL
,
NULL
);
}
else
{
icon
->
tooltip
=
CreateWindowExW
(
WS_EX_TOPMOST
,
TOOLTIPS_CLASSW
,
NULL
,
WS_POPUP
|
TTS_ALWAYSTIP
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
icon
->
window
,
NULL
,
NULL
,
NULL
);
initialized
=
TRUE
;
}
}
/* create tooltip window for icon */
static
void
create_tooltip
(
struct
tray_icon
*
icon
)
{
init_common_controls
();
icon
->
tooltip
=
CreateWindowExW
(
WS_EX_TOPMOST
,
TOOLTIPS_CLASSW
,
NULL
,
WS_POPUP
|
TTS_ALWAYSTIP
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
icon
->
window
,
NULL
,
NULL
,
NULL
);
if
(
icon
->
tooltip
)
{
TTTOOLINFOW
ti
;
...
...
@@ -146,6 +150,101 @@ static void create_tooltip(struct tray_icon *icon)
}
}
static
void
update_balloon_position
(
void
)
{
RECT
rect
;
POINT
pos
;
if
(
!
balloon_icon
)
return
;
GetWindowRect
(
balloon_icon
->
window
,
&
rect
);
pos
.
x
=
(
rect
.
left
+
rect
.
right
)
/
2
;
pos
.
y
=
(
rect
.
top
+
rect
.
bottom
)
/
2
;
if
(
pos
.
x
==
balloon_pos
.
x
&&
pos
.
y
==
balloon_pos
.
y
)
return
;
/* nothing changed */
balloon_pos
=
pos
;
SendMessageW
(
balloon_window
,
TTM_TRACKPOSITION
,
0
,
MAKELONG
(
pos
.
x
,
pos
.
y
));
}
static
void
balloon_create_timer
(
struct
tray_icon
*
icon
)
{
TTTOOLINFOW
ti
;
init_common_controls
();
balloon_window
=
CreateWindowExW
(
WS_EX_TOPMOST
,
TOOLTIPS_CLASSW
,
NULL
,
WS_POPUP
|
TTS_ALWAYSTIP
|
TTS_NOPREFIX
|
TTS_BALLOON
|
TTS_CLOSE
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
icon
->
window
,
NULL
,
NULL
,
NULL
);
memset
(
&
ti
,
0
,
sizeof
(
ti
)
);
ti
.
cbSize
=
sizeof
(
TTTOOLINFOW
);
ti
.
hwnd
=
icon
->
window
;
ti
.
uId
=
(
UINT_PTR
)
icon
->
window
;
ti
.
uFlags
=
TTF_TRACK
|
TTF_IDISHWND
;
ti
.
lpszText
=
icon
->
info_text
;
SendMessageW
(
balloon_window
,
TTM_ADDTOOLW
,
0
,
(
LPARAM
)
&
ti
);
if
((
icon
->
info_flags
&
NIIF_ICONMASK
)
==
NIIF_USER
)
SendMessageW
(
balloon_window
,
TTM_SETTITLEW
,
(
WPARAM
)
icon
->
info_icon
,
(
LPARAM
)
icon
->
info_title
);
else
SendMessageW
(
balloon_window
,
TTM_SETTITLEW
,
icon
->
info_flags
,
(
LPARAM
)
icon
->
info_title
);
balloon_icon
=
icon
;
balloon_pos
.
x
=
balloon_pos
.
y
=
MAXLONG
;
update_balloon_position
();
SendMessageW
(
balloon_window
,
TTM_TRACKACTIVATE
,
TRUE
,
(
LPARAM
)
&
ti
);
KillTimer
(
icon
->
window
,
BALLOON_CREATE_TIMER
);
SetTimer
(
icon
->
window
,
BALLOON_SHOW_TIMER
,
icon
->
info_timeout
,
NULL
);
}
static
BOOL
show_balloon
(
struct
tray_icon
*
icon
)
{
if
(
standalone_tray
&&
!
show_systray
)
return
FALSE
;
/* no systray window */
if
(
!
icon
->
window
)
return
FALSE
;
/* not displayed */
if
(
!
icon
->
info_text
[
0
])
return
FALSE
;
/* no balloon */
balloon_icon
=
icon
;
SetTimer
(
icon
->
window
,
BALLOON_CREATE_TIMER
,
BALLOON_CREATE_TIMEOUT
,
NULL
);
return
TRUE
;
}
static
void
hide_balloon
(
void
)
{
if
(
!
balloon_icon
)
return
;
if
(
balloon_window
)
{
KillTimer
(
balloon_icon
->
window
,
BALLOON_SHOW_TIMER
);
DestroyWindow
(
balloon_window
);
balloon_window
=
0
;
}
else
KillTimer
(
balloon_icon
->
window
,
BALLOON_CREATE_TIMER
);
balloon_icon
=
NULL
;
}
static
void
show_next_balloon
(
void
)
{
struct
tray_icon
*
icon
;
LIST_FOR_EACH_ENTRY
(
icon
,
&
icon_list
,
struct
tray_icon
,
entry
)
if
(
show_balloon
(
icon
))
break
;
}
static
void
update_balloon
(
struct
tray_icon
*
icon
)
{
if
(
balloon_icon
==
icon
)
{
hide_balloon
();
show_balloon
(
icon
);
}
else
if
(
!
balloon_icon
)
{
if
(
!
show_balloon
(
icon
))
return
;
}
if
(
!
balloon_icon
)
show_next_balloon
();
}
static
void
balloon_timer
(
void
)
{
if
(
balloon_icon
)
balloon_icon
->
info_text
[
0
]
=
0
;
/* clear text now that balloon has been shown */
hide_balloon
();
show_next_balloon
();
}
/* synchronize tooltip text with tooltip window */
static
void
update_tooltip_text
(
struct
tray_icon
*
icon
)
{
...
...
@@ -192,8 +291,12 @@ static LRESULT WINAPI standalone_tray_wndproc( HWND hwnd, UINT msg, WPARAM wpara
{
switch
(
msg
)
{
case
WM_MOVE
:
update_balloon_position
();
break
;
case
WM_CLOSE
:
ShowWindow
(
hwnd
,
SW_HIDE
);
hide_balloon
();
show_systray
=
FALSE
;
return
0
;
case
WM_DESTROY
:
...
...
@@ -275,7 +378,7 @@ static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
switch
(
msg
)
{
case
WM_CREATE
:
SetTimer
(
hwnd
,
1
,
1000
,
NULL
);
SetTimer
(
hwnd
,
VALID_WIN_TIMER
,
VALID_WIN_TIMEOUT
,
NULL
);
break
;
case
WM_PAINT
:
...
...
@@ -315,8 +418,23 @@ static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
}
return
0
;
case
WM_WINDOWPOSCHANGED
:
update_balloon_position
();
break
;
case
WM_TIMER
:
if
(
!
IsWindow
(
icon
->
owner
))
delete_icon
(
icon
);
switch
(
wparam
)
{
case
VALID_WIN_TIMER
:
if
(
!
IsWindow
(
icon
->
owner
))
delete_icon
(
icon
);
break
;
case
BALLOON_CREATE_TIMER
:
balloon_create_timer
(
icon
);
break
;
case
BALLOON_SHOW_TIMER
:
balloon_timer
();
break
;
}
return
0
;
case
WM_CLOSE
:
...
...
@@ -467,6 +585,7 @@ static BOOL hide_icon( struct tray_icon *icon )
icon
->
window
=
0
;
icon
->
tooltip
=
0
;
remove_from_standalone_tray
(
icon
);
update_balloon
(
icon
);
return
TRUE
;
}
...
...
@@ -485,6 +604,7 @@ static BOOL show_icon( struct tray_icon *icon )
else
add_to_standalone_tray
(
icon
);
update_balloon
(
icon
);
return
TRUE
;
}
...
...
@@ -529,6 +649,7 @@ static BOOL modify_icon( struct tray_icon *icon, NOTIFYICONDATAW *nid )
icon
->
info_flags
=
nid
->
dwInfoFlags
;
icon
->
info_timeout
=
max
(
min
(
nid
->
u
.
uTimeout
,
BALLOON_SHOW_MAX_TIMEOUT
),
BALLOON_SHOW_MIN_TIMEOUT
);
icon
->
info_icon
=
nid
->
hBalloonIcon
;
update_balloon
(
icon
);
}
if
(
icon
->
state
&
NIS_HIDDEN
)
hide_icon
(
icon
);
else
show_icon
(
icon
);
...
...
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