Merge pull request #454 from Wedge009/SDL2_windows_tray
SDL2 Update for Windows Tray Notification
This commit is contained in:
commit
f862f6964d
3 changed files with 48 additions and 1 deletions
|
@ -1435,6 +1435,9 @@
|
|||
name = "Vladimír Slávik"
|
||||
comment = "Miscellanous text formating and translation engine related help"
|
||||
[/entry]
|
||||
[entry]
|
||||
name = "Wedge009"
|
||||
[/entry]
|
||||
[entry]
|
||||
name = "Yang Yifan (Xara)"
|
||||
[/entry]
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "serialization/string_utils.hpp"
|
||||
#include "serialization/unicode.hpp"
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#include "video.hpp" // CVideo class holds the twindow -> SDL_Window object which contains the handle of the main window
|
||||
#endif
|
||||
|
||||
NOTIFYICONDATA* windows_tray_notification::nid = NULL;
|
||||
bool windows_tray_notification::message_reset = false;
|
||||
|
||||
|
@ -40,16 +44,45 @@ void windows_tray_notification::destroy_tray_icon()
|
|||
|
||||
void windows_tray_notification::handle_system_event(const SDL_Event& event)
|
||||
{
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (event.syswm.msg->msg != WM_TRAYNOTIFY) {
|
||||
#else
|
||||
if (event.syswm.msg->msg.win.msg != WM_TRAYNOTIFY) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (event.syswm.msg->lParam == NIN_BALLOONUSERCLICK) {
|
||||
#else
|
||||
if (event.syswm.msg->msg.win.lParam == NIN_BALLOONUSERCLICK) {
|
||||
#endif
|
||||
switch_to_wesnoth_window();
|
||||
destroy_tray_icon();
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
} else if (event.syswm.msg->lParam == NIN_BALLOONTIMEOUT) {
|
||||
#else
|
||||
} else if (event.syswm.msg->msg.win.lParam == NIN_BALLOONTIMEOUT) {
|
||||
#endif
|
||||
destroy_tray_icon();
|
||||
}
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
// Scenario: More than one notification arrives before the time-out triggers the tray icon destruction.
|
||||
// Problem: Events seem to be triggered differently in SDL 2.0. For the example of two notifications arriving at once:
|
||||
// 1. Balloon created for first notification
|
||||
// 2. Balloon created for second notification (message_reset set to true because of first notification already present)
|
||||
// 3. Balloon time-out for first notification (destroy_tray_icon skips tray icon destruction because of message_reset flag)
|
||||
// 4. SDL 1.2: Balloon time-out for second notification (destroy_tray_icon destroys tray icon)
|
||||
// SDL 2.0: Balloon time-out for second notification event is never received (tray icon remains indefinitely)
|
||||
// This results in the tray icon being 'stuck' until the user quits Wesnoth *and* hovers over the tray icon (and is only then killed off by the OS).
|
||||
// As a less-than-ideal-but-better-than-nothing-solution, call destroy_tray_icon when the user hovers mouse cursor over the tray icon. At least then the tray is 'reset'.
|
||||
// I could not find the matching definition for 0x0200 in the headers, but this message value is received when the mouse cursor is over the tray icon.
|
||||
// Drawback: The tray icon can still get 'stuck' if the user does not move the mouse cursor over the tray icon.
|
||||
// Also, accidental destruction of the tray icon can occur if the user moves the mouse cursor over the tray icon before the balloon for a single notification has expired.
|
||||
else if (event.syswm.msg->msg.win.lParam == 0x0200 && !message_reset) {
|
||||
destroy_tray_icon();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool windows_tray_notification::create_tray_icon()
|
||||
|
@ -157,11 +190,20 @@ HWND windows_tray_notification::get_window_handle()
|
|||
{
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (SDL_GetWMInfo(&wmInfo) != 1) {
|
||||
#else
|
||||
// SDL 1.2 keeps track of window handles internally whereas SDL 2.0 allows the caller control over which window to use
|
||||
if (SDL_GetWindowWMInfo (static_cast<SDL_Window *> (*CVideo::get_window()), &wmInfo) != SDL_TRUE) {
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
return wmInfo.window;
|
||||
#else
|
||||
return wmInfo.info.win.window;
|
||||
#endif
|
||||
}
|
||||
|
||||
void windows_tray_notification::switch_to_wesnoth_window()
|
||||
|
|
|
@ -543,7 +543,9 @@ int CVideo::setMode( int x, int y, int bits_per_pixel, int flags )
|
|||
fullScreen = (flags & FULL_SCREEN) != 0;
|
||||
|
||||
if(!window) {
|
||||
window = new sdl::twindow("", 0, 0, x, y, flags, SDL_RENDERER_SOFTWARE);
|
||||
// SDL_WINDOWPOS_UNDEFINED allows SDL to centre the window in the display instead of using a fixed initial position.
|
||||
// Note that x and y in this particular case refer to width and height of the window, not co-ordinates.
|
||||
window = new sdl::twindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, x, y, flags, SDL_RENDERER_SOFTWARE);
|
||||
} else {
|
||||
if(fullScreen) {
|
||||
window->full_screen();
|
||||
|
|
Loading…
Add table
Reference in a new issue