1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

tray notification for windows

This commit is contained in:
Andrii Danylchenko 2020-03-22 15:57:13 +02:00 committed by Andrii Danylchenko
parent 45bdacb119
commit 2fc7cf02b0
6 changed files with 209 additions and 1 deletions

View File

@ -59,6 +59,7 @@
#include "gui/CAnimation.h" #include "gui/CAnimation.h"
#include "../lib/serializer/Connection.h" #include "../lib/serializer/Connection.h"
#include "CServerHandler.h" #include "CServerHandler.h"
#include "gui/NotificationHandler.h"
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -1225,6 +1226,11 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
SDL_RenderClear(mainRenderer); SDL_RenderClear(mainRenderer);
SDL_RenderPresent(mainRenderer); SDL_RenderPresent(mainRenderer);
if(!settings["session"]["headless"].Bool() && settings["general"]["notifications"].Bool())
{
NotificationHandler::init(mainWindow);
}
return true; return true;
} }
@ -1355,6 +1361,13 @@ static void handleEvent(SDL_Event & ev)
} }
return; return;
} }
else if(ev.type == SDL_SYSWMEVENT)
{
if(!settings["session"]["headless"].Bool() && settings["general"]["notifications"].Bool())
{
NotificationHandler::handleSdlEvent(ev);
}
}
//preprocessing //preprocessing
if(ev.type == SDL_MOUSEMOTION) if(ev.type == SDL_MOUSEMOTION)
@ -1430,6 +1443,11 @@ void handleQuit(bool ask)
boost::this_thread::sleep(boost::posix_time::milliseconds(750));//??? boost::this_thread::sleep(boost::posix_time::milliseconds(750));//???
if(!settings["session"]["headless"].Bool()) if(!settings["session"]["headless"].Bool())
{ {
if(settings["general"]["notifications"].Bool())
{
NotificationHandler::destroy();
}
cleanupRenderer(); cleanupRenderer();
if(nullptr != mainRenderer) if(nullptr != mainRenderer)

View File

@ -14,6 +14,7 @@ set(client_SRCS
gui/Fonts.cpp gui/Fonts.cpp
gui/Geometries.cpp gui/Geometries.cpp
gui/SDL_Extensions.cpp gui/SDL_Extensions.cpp
gui/NotificationHandler.cpp
widgets/AdventureMapClasses.cpp widgets/AdventureMapClasses.cpp
widgets/Buttons.cpp widgets/Buttons.cpp
@ -88,6 +89,7 @@ set(client_HEADERS
gui/SDL_Compat.h gui/SDL_Compat.h
gui/SDL_Extensions.h gui/SDL_Extensions.h
gui/SDL_Pixels.h gui/SDL_Pixels.h
gui/NotificationHandler.h
widgets/AdventureMapClasses.h widgets/AdventureMapClasses.h
widgets/Buttons.h widgets/Buttons.h

View File

@ -62,6 +62,7 @@
#include "CServerHandler.h" #include "CServerHandler.h"
// FIXME: only needed for CGameState::mutex // FIXME: only needed for CGameState::mutex
#include "../lib/CGameState.h" #include "../lib/CGameState.h"
#include "gui/NotificationHandler.h"
// The macro below is used to mark functions that are called by client when game state changes. // The macro below is used to mark functions that are called by client when game state changes.
@ -166,6 +167,8 @@ void CPlayerInterface::yourTurn()
GH.curInt = this; GH.curInt = this;
adventureInt->selection = nullptr; adventureInt->selection = nullptr;
NotificationHandler::notify("Your turn");
std::string prefix = settings["session"]["saveprefix"].String(); std::string prefix = settings["session"]["saveprefix"].String();
int frequency = static_cast<int>(settings["general"]["saveFrequency"].Integer()); int frequency = static_cast<int>(settings["general"]["saveFrequency"].Integer());
if (firstCall) if (firstCall)

View File

@ -0,0 +1,159 @@
/*
* NotificationHandler.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "NotificationHandler.h"
#include <SDL_video.h>
#include <SDL_syswm.h>
#if defined(VCMI_WINDOWS) && defined(_WIN64)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <shellapi.h>
// C RunTime Header Files
#define WM_USER_SHELLICON WM_USER + 1
// Global Variables:
struct NotificationState
{
HINSTANCE hInst; // current instance
NOTIFYICONDATA niData; // notify icon data
bool initialized = false;
SDL_Window * window;
};
NotificationState state;
void NotificationHandler::notify(std::string msg)
{
NOTIFYICONDATA niData;
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(state.window, &info))
return;
if(info.info.win.window == GetForegroundWindow())
return;
ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
niData.cbSize = sizeof(NOTIFYICONDATA);
niData.hWnd = info.info.win.window;
niData.uID = 1;
niData.uFlags = NIF_INFO | NIF_MESSAGE;
niData.uCallbackMessage = WM_USER_SHELLICON;
niData.dwInfoFlags = NIIF_INFO;
msg.copy(niData.szInfo, msg.length());
Shell_NotifyIcon(NIM_MODIFY, &niData);
}
void NotificationHandler::init(SDL_Window * window)
{
state.window = window;
if(state.initialized)
return;
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
NOTIFYICONDATA niData;
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(state.window, &info))
return;
ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
state.hInst = (HINSTANCE)GetModuleHandle("VCMI_client.exe");
niData.cbSize = sizeof(NOTIFYICONDATA);
niData.hWnd = info.info.win.window;
niData.uID = 1;
niData.uFlags = NIF_ICON | NIF_MESSAGE;
niData.uCallbackMessage = WM_USER_SHELLICON;
niData.hIcon = (HICON)LoadImage(
state.hInst,
"IDI_ICON1",
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTSIZE);
Shell_NotifyIcon(NIM_ADD, &niData);
state.initialized = true;
}
void NotificationHandler::destroy()
{
NOTIFYICONDATA niData;
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(state.window, &info))
return;
ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
niData.cbSize = sizeof(NOTIFYICONDATA);
niData.hWnd = info.info.win.window;
niData.uID = 1;
Shell_NotifyIcon(NIM_DELETE, &niData);
}
bool NotificationHandler::handleSdlEvent(const SDL_Event & ev)
{
if(ev.syswm.msg->msg.win.msg == WM_USER_SHELLICON)
{
auto winMsg = LOWORD(ev.syswm.msg->msg.win.lParam);
if(winMsg == WM_LBUTTONUP || winMsg == NIN_BALLOONUSERCLICK)
{
SDL_MinimizeWindow(state.window);
SDL_RestoreWindow(state.window);
SDL_RaiseWindow(state.window);
return true;
}
}
return false;
}
#else
void NotificationHandler::notify(std::string msg)
{
}
void NotificationHandler::init(SDL_Window * window)
{
}
void NotificationHandler::destroy()
{
}
bool NotificationHandler::handleSdlEvent(const SDL_Event & ev)
{
return false;
}
#endif

View File

@ -0,0 +1,22 @@
/*
* NotificationHandler.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include <SDL_events.h>
class NotificationHandler
{
public:
static void notify(std::string msg);
static void init(SDL_Window * window);
static bool handleSdlEvent(const SDL_Event & ev);
static void destroy();
};

View File

@ -17,7 +17,7 @@
"type" : "object", "type" : "object",
"default": {}, "default": {},
"additionalProperties" : false, "additionalProperties" : false,
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps", "saveFrequency" ], "required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps", "saveFrequency", "notifications" ],
"properties" : { "properties" : {
"playerName" : { "playerName" : {
"type":"string", "type":"string",
@ -62,6 +62,10 @@
"saveFrequency" : { "saveFrequency" : {
"type" : "number", "type" : "number",
"default" : 1 "default" : 1
},
"notifications" : {
"type" : "boolean",
"default" : false
} }
} }
}, },