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
52246fb9
Commit
52246fb9
authored
Apr 08, 2008
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11: Move all the embedded systray window support to winex11.drv.
parent
a643337c
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
454 additions
and
101 deletions
+454
-101
Makefile.in
dlls/winex11.drv/Makefile.in
+2
-0
systray.c
dlls/winex11.drv/systray.c
+439
-0
window.c
dlls/winex11.drv/window.c
+0
-90
winex11.drv.spec
dlls/winex11.drv/winex11.drv.spec
+1
-1
x11drv.h
dlls/winex11.drv/x11drv.h
+0
-2
x11drv_main.c
dlls/winex11.drv/x11drv_main.c
+0
-2
systray.c
programs/explorer/systray.c
+12
-6
No files found.
dlls/winex11.drv/Makefile.in
View file @
52246fb9
...
...
@@ -4,6 +4,7 @@ SRCDIR = @srcdir@
VPATH
=
@srcdir@
MODULE
=
winex11.drv
IMPORTS
=
user32 gdi32 advapi32 imm32 kernel32 ntdll
DELAYIMPORTS
=
comctl32
EXTRAINCL
=
@X_CFLAGS@
EXTRALIBS
=
@X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
...
...
@@ -30,6 +31,7 @@ C_SRCS = \
pen.c
\
scroll.c
\
settings.c
\
systray.c
\
text.c
\
window.c
\
winpos.c
\
...
...
dlls/winex11.drv/systray.c
0 → 100644
View file @
52246fb9
/*
* X11 system tray management
*
* Copyright (C) 2004 Mike Hearn, for CodeWeavers
* Copyright (C) 2005 Robert Shearman
* Copyright (C) 2008 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <X11/Xlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "commctrl.h"
#include "shellapi.h"
#include "x11drv.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
systray
);
/* an individual systray icon */
struct
tray_icon
{
struct
list
entry
;
HICON
image
;
/* the image to render */
HWND
owner
;
/* the HWND passed in to the Shell_NotifyIcon call */
HWND
window
;
/* the adaptor window */
HWND
tooltip
;
/* Icon tooltip */
UINT
id
;
/* the unique id given by the app */
UINT
callback_message
;
BOOL
hidden
;
/* icon display state */
WCHAR
tiptext
[
128
];
/* Tooltip text. If empty => tooltip disabled */
};
static
struct
list
icon_list
=
LIST_INIT
(
icon_list
);
static
const
WCHAR
tray_classname
[]
=
{
'_'
,
'_'
,
'w'
,
'i'
,
'n'
,
'e'
,
'x'
,
'1'
,
'1'
,
'_'
,
't'
,
'r'
,
'a'
,
'y'
,
'_'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
0
};
static
BOOL
delete_icon
(
struct
tray_icon
*
icon
);
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
#define XEMBED_MAPPED (1 << 0)
#define ICON_BORDER 2
/* retrieves icon record by owner window and ID */
static
struct
tray_icon
*
get_icon
(
HWND
owner
,
UINT
id
)
{
struct
tray_icon
*
this
;
LIST_FOR_EACH_ENTRY
(
this
,
&
icon_list
,
struct
tray_icon
,
entry
)
if
((
this
->
id
==
id
)
&&
(
this
->
owner
==
owner
))
return
this
;
return
NULL
;
}
/* create tooltip window for icon */
static
void
create_tooltip
(
struct
tray_icon
*
icon
)
{
static
BOOL
tooltips_initialized
=
FALSE
;
if
(
!
tooltips_initialized
)
{
INITCOMMONCONTROLSEX
init_tooltip
;
init_tooltip
.
dwSize
=
sizeof
(
INITCOMMONCONTROLSEX
);
init_tooltip
.
dwICC
=
ICC_TAB_CLASSES
;
InitCommonControlsEx
(
&
init_tooltip
);
tooltips_initialized
=
TRUE
;
}
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
;
ZeroMemory
(
&
ti
,
sizeof
(
ti
));
ti
.
cbSize
=
sizeof
(
TTTOOLINFOW
);
ti
.
uFlags
=
TTF_SUBCLASS
|
TTF_IDISHWND
;
ti
.
hwnd
=
icon
->
window
;
ti
.
uId
=
(
UINT_PTR
)
icon
->
window
;
ti
.
lpszText
=
icon
->
tiptext
;
SendMessageW
(
icon
->
tooltip
,
TTM_ADDTOOLW
,
0
,
(
LPARAM
)
&
ti
);
}
}
/* synchronize tooltip text with tooltip window */
static
void
update_tooltip_text
(
struct
tray_icon
*
icon
)
{
TTTOOLINFOW
ti
;
ZeroMemory
(
&
ti
,
sizeof
(
ti
));
ti
.
cbSize
=
sizeof
(
TTTOOLINFOW
);
ti
.
uFlags
=
TTF_SUBCLASS
|
TTF_IDISHWND
;
ti
.
hwnd
=
icon
->
window
;
ti
.
uId
=
(
UINT_PTR
)
icon
->
window
;
ti
.
lpszText
=
icon
->
tiptext
;
SendMessageW
(
icon
->
tooltip
,
TTM_UPDATETIPTEXTW
,
0
,
(
LPARAM
)
&
ti
);
}
/* window procedure for the tray window */
static
LRESULT
WINAPI
tray_wndproc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
struct
tray_icon
*
icon
=
NULL
;
BOOL
ret
;
WINE_TRACE
(
"hwnd=%p, msg=0x%x
\n
"
,
hwnd
,
msg
);
/* set the icon data for the window from the data passed into CreateWindow */
if
(
msg
==
WM_NCCREATE
)
SetWindowLongPtrW
(
hwnd
,
GWLP_USERDATA
,
(
LPARAM
)((
const
CREATESTRUCTW
*
)
lparam
)
->
lpCreateParams
);
icon
=
(
struct
tray_icon
*
)
GetWindowLongPtrW
(
hwnd
,
GWLP_USERDATA
);
switch
(
msg
)
{
case
WM_PAINT
:
{
PAINTSTRUCT
ps
;
RECT
rc
;
HDC
hdc
;
int
cx
=
GetSystemMetrics
(
SM_CXSMICON
);
int
cy
=
GetSystemMetrics
(
SM_CYSMICON
);
hdc
=
BeginPaint
(
hwnd
,
&
ps
);
GetClientRect
(
hwnd
,
&
rc
);
TRACE
(
"painting rect %s
\n
"
,
wine_dbgstr_rect
(
&
rc
));
DrawIconEx
(
hdc
,
(
rc
.
left
+
rc
.
right
-
cx
)
/
2
,
(
rc
.
top
+
rc
.
bottom
-
cy
)
/
2
,
icon
->
image
,
cx
,
cy
,
0
,
0
,
DI_DEFAULTSIZE
|
DI_NORMAL
);
EndPaint
(
hwnd
,
&
ps
);
break
;
}
case
WM_MOUSEMOVE
:
case
WM_LBUTTONDOWN
:
case
WM_LBUTTONUP
:
case
WM_RBUTTONDOWN
:
case
WM_RBUTTONUP
:
case
WM_MBUTTONDOWN
:
case
WM_MBUTTONUP
:
case
WM_LBUTTONDBLCLK
:
case
WM_RBUTTONDBLCLK
:
case
WM_MBUTTONDBLCLK
:
/* notify the owner hwnd of the message */
TRACE
(
"relaying 0x%x
\n
"
,
msg
);
ret
=
PostMessageW
(
icon
->
owner
,
icon
->
callback_message
,
(
WPARAM
)
icon
->
id
,
(
LPARAM
)
msg
);
if
(
!
ret
&&
(
GetLastError
()
==
ERROR_INVALID_WINDOW_HANDLE
))
{
WARN
(
"application window was destroyed, removing icon %u
\n
"
,
icon
->
id
);
delete_icon
(
icon
);
}
break
;
default:
return
DefWindowProcW
(
hwnd
,
msg
,
wparam
,
lparam
);
}
return
0
;
}
/* find the X11 window owner the system tray selection */
static
Window
get_systray_selection_owner
(
Display
*
display
)
{
static
Atom
systray_atom
;
Window
ret
;
if
(
root_window
!=
DefaultRootWindow
(
display
))
return
0
;
wine_tsx11_lock
();
if
(
!
systray_atom
)
{
if
(
DefaultScreen
(
display
)
==
0
)
systray_atom
=
x11drv_atom
(
_NET_SYSTEM_TRAY_S0
);
else
{
char
systray_buffer
[
29
];
/* strlen(_NET_SYSTEM_TRAY_S4294967295)+1 */
sprintf
(
systray_buffer
,
"_NET_SYSTEM_TRAY_S%u"
,
DefaultScreen
(
display
)
);
systray_atom
=
XInternAtom
(
display
,
systray_buffer
,
False
);
}
}
ret
=
XGetSelectionOwner
(
display
,
systray_atom
);
wine_tsx11_unlock
();
return
ret
;
}
/* dock the given X window with the NETWM system tray */
static
void
dock_systray_window
(
HWND
hwnd
,
Window
systray_window
)
{
Display
*
display
=
thread_display
();
struct
x11drv_win_data
*
data
;
XEvent
ev
;
unsigned
long
info
[
2
];
if
(
!
(
data
=
X11DRV_get_win_data
(
hwnd
))
&&
!
(
data
=
X11DRV_create_win_data
(
hwnd
)))
return
;
TRACE
(
"icon window %p/%lx managed %u
\n
"
,
data
->
hwnd
,
data
->
whole_window
,
data
->
managed
);
/* the window _cannot_ be mapped if we intend to dock with an XEMBED tray */
assert
(
!
data
->
mapped
);
/* set XEMBED protocol data on the window */
info
[
0
]
=
0
;
/* protocol version */
info
[
1
]
=
XEMBED_MAPPED
;
/* flags */
wine_tsx11_lock
();
XChangeProperty
(
display
,
data
->
whole_window
,
x11drv_atom
(
_XEMBED_INFO
),
x11drv_atom
(
_XEMBED_INFO
),
32
,
PropModeReplace
,
(
unsigned
char
*
)
info
,
2
);
/* send the docking request message */
ev
.
xclient
.
type
=
ClientMessage
;
ev
.
xclient
.
window
=
systray_window
;
ev
.
xclient
.
message_type
=
x11drv_atom
(
_NET_SYSTEM_TRAY_OPCODE
);
ev
.
xclient
.
format
=
32
;
ev
.
xclient
.
data
.
l
[
0
]
=
CurrentTime
;
ev
.
xclient
.
data
.
l
[
1
]
=
SYSTEM_TRAY_REQUEST_DOCK
;
ev
.
xclient
.
data
.
l
[
2
]
=
data
->
whole_window
;
ev
.
xclient
.
data
.
l
[
3
]
=
0
;
ev
.
xclient
.
data
.
l
[
4
]
=
0
;
XSendEvent
(
display
,
systray_window
,
False
,
NoEventMask
,
&
ev
);
wine_tsx11_unlock
();
data
->
mapped
=
TRUE
;
data
->
wm_state
=
NormalState
;
}
/* hide a tray icon */
static
BOOL
hide_icon
(
struct
tray_icon
*
icon
)
{
TRACE
(
"id=0x%x, hwnd=%p
\n
"
,
icon
->
id
,
icon
->
owner
);
if
(
!
icon
->
window
||
icon
->
hidden
)
return
TRUE
;
/* already hidden */
if
(
icon
->
window
)
{
DestroyWindow
(
icon
->
window
);
DestroyWindow
(
icon
->
tooltip
);
}
icon
->
hidden
=
TRUE
;
return
TRUE
;
}
/* make the icon visible */
static
BOOL
show_icon
(
struct
tray_icon
*
icon
)
{
RECT
rect
;
static
BOOL
class_registered
;
Window
systray_window
;
TRACE
(
"id=0x%x, hwnd=%p
\n
"
,
icon
->
id
,
icon
->
owner
);
if
(
icon
->
window
&&
!
icon
->
hidden
)
return
TRUE
;
/* already shown */
if
(
!
class_registered
)
{
WNDCLASSEXW
class
;
ZeroMemory
(
&
class
,
sizeof
(
class
)
);
class
.
cbSize
=
sizeof
(
class
);
class
.
lpfnWndProc
=
tray_wndproc
;
class
.
hCursor
=
LoadCursorW
(
0
,
(
LPCWSTR
)
IDC_ARROW
);
class
.
lpszClassName
=
tray_classname
;
class
.
hbrBackground
=
(
HBRUSH
)
COLOR_WINDOW
;
class
.
style
=
CS_HREDRAW
|
CS_VREDRAW
|
CS_DBLCLKS
;
if
(
!
RegisterClassExW
(
&
class
)
&&
GetLastError
()
!=
ERROR_CLASS_ALREADY_EXISTS
)
{
WINE_ERR
(
"Could not register tray window class
\n
"
);
return
FALSE
;
}
class_registered
=
TRUE
;
}
if
(
!
(
systray_window
=
get_systray_selection_owner
(
thread_display
()
)))
return
FALSE
;
rect
.
left
=
0
;
rect
.
top
=
0
;
rect
.
right
=
GetSystemMetrics
(
SM_CXSMICON
)
+
2
*
ICON_BORDER
;
rect
.
bottom
=
GetSystemMetrics
(
SM_CYSMICON
)
+
2
*
ICON_BORDER
;
icon
->
window
=
CreateWindowExW
(
WS_EX_APPWINDOW
,
tray_classname
,
NULL
,
WS_CLIPSIBLINGS
|
WS_POPUP
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
rect
.
right
-
rect
.
left
,
rect
.
bottom
-
rect
.
top
,
NULL
,
NULL
,
NULL
,
icon
);
create_tooltip
(
icon
);
dock_systray_window
(
icon
->
window
,
systray_window
);
ShowWindow
(
icon
->
window
,
SW_SHOWNA
);
icon
->
hidden
=
FALSE
;
return
TRUE
;
}
/* Modifies an existing icon record */
static
BOOL
modify_icon
(
struct
tray_icon
*
icon
,
NOTIFYICONDATAW
*
nid
)
{
TRACE
(
"id=0x%x hwnd=%p flags=%x
\n
"
,
nid
->
uID
,
nid
->
hWnd
,
nid
->
uFlags
);
if
((
nid
->
uFlags
&
NIF_STATE
)
&&
(
nid
->
dwStateMask
&
NIS_HIDDEN
))
{
if
(
nid
->
dwState
&
NIS_HIDDEN
)
hide_icon
(
icon
);
else
show_icon
(
icon
);
}
/* startup case*/
if
(
!
icon
->
window
&&
!
icon
->
hidden
)
show_icon
(
icon
);
if
(
nid
->
uFlags
&
NIF_ICON
)
{
if
(
icon
->
image
)
DestroyIcon
(
icon
->
image
);
icon
->
image
=
CopyIcon
(
nid
->
hIcon
);
if
(
!
icon
->
hidden
)
RedrawWindow
(
icon
->
window
,
NULL
,
NULL
,
RDW_ERASE
|
RDW_INVALIDATE
|
RDW_UPDATENOW
);
}
if
(
nid
->
uFlags
&
NIF_MESSAGE
)
{
icon
->
callback_message
=
nid
->
uCallbackMessage
;
}
if
(
nid
->
uFlags
&
NIF_TIP
)
{
lstrcpynW
(
icon
->
tiptext
,
nid
->
szTip
,
sizeof
(
icon
->
tiptext
)
/
sizeof
(
WCHAR
));
if
(
!
icon
->
hidden
)
update_tooltip_text
(
icon
);
}
if
(
nid
->
uFlags
&
NIF_INFO
&&
nid
->
cbSize
>=
NOTIFYICONDATAA_V2_SIZE
)
{
FIXME
(
"balloon tip title %s, message %s
\n
"
,
wine_dbgstr_w
(
nid
->
szInfoTitle
),
wine_dbgstr_w
(
nid
->
szInfo
));
}
return
TRUE
;
}
/* Adds a new icon record to the list */
static
BOOL
add_icon
(
NOTIFYICONDATAW
*
nid
)
{
struct
tray_icon
*
icon
;
WINE_TRACE
(
"id=0x%x, hwnd=%p
\n
"
,
nid
->
uID
,
nid
->
hWnd
);
if
((
icon
=
get_icon
(
nid
->
hWnd
,
nid
->
uID
)))
{
WINE_WARN
(
"duplicate tray icon add, buggy app?
\n
"
);
return
FALSE
;
}
if
(
!
(
icon
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
icon
))))
{
WINE_ERR
(
"out of memory
\n
"
);
return
FALSE
;
}
ZeroMemory
(
icon
,
sizeof
(
struct
tray_icon
));
icon
->
id
=
nid
->
uID
;
icon
->
owner
=
nid
->
hWnd
;
list_add_tail
(
&
icon_list
,
&
icon
->
entry
);
/*
* Both icon->window and icon->hidden are zero. modify_icon function
* will treat this case as a startup, i.e. icon window will be created if
* NIS_HIDDEN flag is not set.
*/
return
modify_icon
(
icon
,
nid
);
}
/* delete tray icon window and icon structure */
static
BOOL
delete_icon
(
struct
tray_icon
*
icon
)
{
hide_icon
(
icon
);
list_remove
(
&
icon
->
entry
);
DestroyIcon
(
icon
->
image
);
HeapFree
(
GetProcessHeap
(),
0
,
icon
);
return
TRUE
;
}
/***********************************************************************
* wine_notify_icon (X11DRV.@)
*
* Driver-side implementation of Shell_NotifyIcon.
*/
BOOL
wine_notify_icon
(
DWORD
msg
,
NOTIFYICONDATAW
*
data
)
{
BOOL
ret
=
FALSE
;
struct
tray_icon
*
icon
;
Window
owner
;
switch
(
msg
)
{
case
NIM_ADD
:
if
((
owner
=
get_systray_selection_owner
(
thread_display
()
)))
ret
=
add_icon
(
data
);
break
;
case
NIM_DELETE
:
if
((
icon
=
get_icon
(
data
->
hWnd
,
data
->
uID
)))
ret
=
delete_icon
(
icon
);
break
;
case
NIM_MODIFY
:
if
((
icon
=
get_icon
(
data
->
hWnd
,
data
->
uID
)))
ret
=
modify_icon
(
icon
,
data
);
break
;
default:
FIXME
(
"unhandled tray message: %u
\n
"
,
msg
);
break
;
}
return
ret
;
}
dlls/winex11.drv/window.c
View file @
52246fb9
...
...
@@ -64,9 +64,6 @@ static const char gl_drawable_prop[] = "__wine_x11_gl_drawable";
static
const
char
pixmap_prop
[]
=
"__wine_x11_pixmap"
;
static
const
char
managed_prop
[]
=
"__wine_x11_managed"
;
/* for XDG systray icons */
#define SYSTEM_TRAY_REQUEST_DOCK 0
extern
int
usexcomposite
;
/***********************************************************************
...
...
@@ -692,93 +689,6 @@ static void set_icon_hints( Display *display, struct x11drv_win_data *data, HICO
}
}
/***********************************************************************
* wine_make_systray_window (X11DRV.@)
*
* Docks the given X window with the NETWM system tray.
*/
void
X11DRV_make_systray_window
(
HWND
hwnd
)
{
static
Atom
systray_atom
;
Display
*
display
=
thread_display
();
struct
x11drv_win_data
*
data
;
Window
systray_window
;
if
(
root_window
!=
DefaultRootWindow
(
display
))
return
;
if
(
!
(
data
=
X11DRV_get_win_data
(
hwnd
))
&&
!
(
data
=
X11DRV_create_win_data
(
hwnd
)))
return
;
wine_tsx11_lock
();
if
(
!
systray_atom
)
{
if
(
DefaultScreen
(
display
)
==
0
)
systray_atom
=
x11drv_atom
(
_NET_SYSTEM_TRAY_S0
);
else
{
char
systray_buffer
[
29
];
/* strlen(_NET_SYSTEM_TRAY_S4294967295)+1 */
sprintf
(
systray_buffer
,
"_NET_SYSTEM_TRAY_S%u"
,
DefaultScreen
(
display
)
);
systray_atom
=
XInternAtom
(
display
,
systray_buffer
,
False
);
}
}
systray_window
=
XGetSelectionOwner
(
display
,
systray_atom
);
wine_tsx11_unlock
();
TRACE
(
"Docking tray icon %p
\n
"
,
data
->
hwnd
);
if
(
systray_window
!=
None
)
{
XEvent
ev
;
unsigned
long
info
[
2
];
/* the window _cannot_ be mapped if we intend to dock with an XEMBED tray */
if
(
data
->
mapped
)
FIXME
(
"trying to dock mapped window %p
\n
"
,
data
->
hwnd
);
/* set XEMBED protocol data on the window */
info
[
0
]
=
0
;
/* protocol version */
info
[
1
]
=
1
;
/* mapped = true */
wine_tsx11_lock
();
XChangeProperty
(
display
,
data
->
whole_window
,
x11drv_atom
(
_XEMBED_INFO
),
x11drv_atom
(
_XEMBED_INFO
),
32
,
PropModeReplace
,
(
unsigned
char
*
)
info
,
2
);
/* send the docking request message */
ev
.
xclient
.
type
=
ClientMessage
;
ev
.
xclient
.
window
=
systray_window
;
ev
.
xclient
.
message_type
=
x11drv_atom
(
_NET_SYSTEM_TRAY_OPCODE
);
ev
.
xclient
.
format
=
32
;
ev
.
xclient
.
data
.
l
[
0
]
=
CurrentTime
;
ev
.
xclient
.
data
.
l
[
1
]
=
SYSTEM_TRAY_REQUEST_DOCK
;
ev
.
xclient
.
data
.
l
[
2
]
=
data
->
whole_window
;
ev
.
xclient
.
data
.
l
[
3
]
=
0
;
ev
.
xclient
.
data
.
l
[
4
]
=
0
;
XSendEvent
(
display
,
systray_window
,
False
,
NoEventMask
,
&
ev
);
wine_tsx11_unlock
();
data
->
mapped
=
TRUE
;
}
else
{
int
val
=
1
;
/* fall back to he KDE hints if the WM doesn't support XEMBED'ed
* systrays */
wine_tsx11_lock
();
XChangeProperty
(
display
,
data
->
whole_window
,
x11drv_atom
(
KWM_DOCKWINDOW
),
x11drv_atom
(
KWM_DOCKWINDOW
),
32
,
PropModeReplace
,
(
unsigned
char
*
)
&
val
,
1
);
XChangeProperty
(
display
,
data
->
whole_window
,
x11drv_atom
(
_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR
),
XA_WINDOW
,
32
,
PropModeReplace
,
(
unsigned
char
*
)
&
data
->
whole_window
,
1
);
wine_tsx11_unlock
();
}
}
/***********************************************************************
* set_size_hints
...
...
dlls/winex11.drv/winex11.drv.spec
View file @
52246fb9
...
...
@@ -129,7 +129,7 @@
@ cdecl wine_create_desktop(long long) X11DRV_create_desktop
# System tray
@ cdecl wine_
make_systray_window(long) X11DRV_make_systray_window
@ cdecl wine_
notify_icon(long ptr)
# XIM
@ cdecl ForceXIMReset(long) X11DRV_ForceXIMReset
...
...
dlls/winex11.drv/x11drv.h
View file @
52246fb9
...
...
@@ -582,12 +582,10 @@ enum x11drv_atoms
XATOM_WM_DELETE_WINDOW
,
XATOM_WM_STATE
,
XATOM_WM_TAKE_FOCUS
,
XATOM_KWM_DOCKWINDOW
,
XATOM_DndProtocol
,
XATOM_DndSelection
,
XATOM__ICC_PROFILE
,
XATOM__MOTIF_WM_HINTS
,
XATOM__KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR
,
XATOM__NET_SUPPORTED
,
XATOM__NET_SYSTEM_TRAY_OPCODE
,
XATOM__NET_SYSTEM_TRAY_S0
,
...
...
dlls/winex11.drv/x11drv_main.c
View file @
52246fb9
...
...
@@ -125,12 +125,10 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"WM_DELETE_WINDOW"
,
"WM_STATE"
,
"WM_TAKE_FOCUS"
,
"KWM_DOCKWINDOW"
,
"DndProtocol"
,
"DndSelection"
,
"_ICC_PROFILE"
,
"_MOTIF_WM_HINTS"
,
"_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR"
,
"_NET_SUPPORTED"
,
"_NET_SYSTEM_TRAY_OPCODE"
,
"_NET_SYSTEM_TRAY_S0"
,
...
...
programs/explorer/systray.c
View file @
52246fb9
...
...
@@ -45,6 +45,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(systray);
#define IS_OPTION_FALSE(ch) \
((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
static
BOOL
(
*
wine_notify_icon
)(
DWORD
,
NOTIFYICONDATAW
*
);
static
const
WCHAR
adaptor_classname
[]
=
/* Adaptor */
{
'A'
,
'd'
,
'a'
,
'p'
,
't'
,
'o'
,
'r'
,
0
};
/* tray state */
...
...
@@ -146,7 +148,6 @@ static void update_tooltip_text(struct icon *icon)
*/
static
BOOL
display_icon
(
struct
icon
*
icon
,
BOOL
hide
)
{
HMODULE
x11drv
=
GetModuleHandleA
(
"winex11.drv"
);
RECT
rect
;
static
const
WCHAR
adaptor_windowname
[]
=
/* Wine System Tray Adaptor */
{
'W'
,
'i'
,
'n'
,
'e'
,
' '
,
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
' '
,
'T'
,
'r'
,
'a'
,
'y'
,
' '
,
'A'
,
'd'
,
'a'
,
'p'
,
't'
,
'o'
,
'r'
,
0
};
...
...
@@ -182,11 +183,6 @@ static BOOL display_icon(struct icon *icon, BOOL hide)
rect
.
right
-
rect
.
left
,
rect
.
bottom
-
rect
.
top
,
NULL
,
NULL
,
NULL
,
icon
);
if
(
x11drv
)
{
void
(
*
make_systray_window
)(
HWND
)
=
(
void
*
)
GetProcAddress
(
x11drv
,
"wine_make_systray_window"
);
if
(
make_systray_window
)
make_systray_window
(
icon
->
window
);
}
if
(
!
hide_systray
)
ShowWindow
(
icon
->
window
,
SW_SHOWNA
);
...
...
@@ -355,6 +351,12 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds)
buffer
,
buffer
+
cbMaskBits
);
}
if
(
wine_notify_icon
&&
wine_notify_icon
(
cds
->
dwData
,
&
nid
))
{
if
(
nid
.
uFlags
&
NIF_ICON
)
DestroyIcon
(
nid
.
hIcon
);
return
TRUE
;
}
switch
(
cds
->
dwData
)
{
case
NIM_ADD
:
...
...
@@ -484,6 +486,7 @@ static BOOL is_systray_hidden(void)
/* this function creates the listener window */
void
initialize_systray
(
void
)
{
HMODULE
x11drv
;
WNDCLASSEX
class
;
static
const
WCHAR
classname
[]
=
/* Shell_TrayWnd */
{
'S'
,
'h'
,
'e'
,
'l'
,
'l'
,
'_'
,
'T'
,
'r'
,
'a'
,
'y'
,
'W'
,
'n'
,
'd'
,
0
};
static
const
WCHAR
winname
[]
=
/* Wine Systray Listener */
...
...
@@ -491,6 +494,9 @@ void initialize_systray(void)
WINE_TRACE
(
"initiaizing
\n
"
);
if
((
x11drv
=
GetModuleHandleA
(
"winex11.drv"
)))
wine_notify_icon
=
(
void
*
)
GetProcAddress
(
x11drv
,
"wine_notify_icon"
);
hide_systray
=
is_systray_hidden
();
list_init
(
&
tray
.
icons
);
...
...
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