2016-06-16 12:59:54 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
2018-01-03 10:23:14 +00:00
|
|
|
the official desktop application for the Telegram messaging service.
|
2016-06-16 12:59:54 +00:00
|
|
|
|
2018-01-03 10:23:14 +00:00
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
2016-06-16 12:59:54 +00:00
|
|
|
*/
|
|
|
|
#include "platform/win/windows_event_filter.h"
|
|
|
|
|
|
|
|
#include "mainwindow.h"
|
2017-04-15 18:48:54 +00:00
|
|
|
#include "auth_session.h"
|
2016-06-16 12:59:54 +00:00
|
|
|
|
|
|
|
namespace Platform {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
EventFilter *instance = nullptr;
|
|
|
|
|
|
|
|
int menuShown = 0, menuHidden = 0;
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
EventFilter *EventFilter::createInstance() {
|
|
|
|
destroy();
|
|
|
|
instance = new EventFilter();
|
|
|
|
return getInstance();
|
|
|
|
}
|
|
|
|
|
|
|
|
EventFilter *EventFilter::getInstance() {
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EventFilter::destroy() {
|
|
|
|
delete instance;
|
|
|
|
instance = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) {
|
|
|
|
auto wnd = App::wnd();
|
|
|
|
if (!wnd) return false;
|
|
|
|
|
|
|
|
MSG *msg = (MSG*)message;
|
|
|
|
if (msg->message == WM_ENDSESSION) {
|
|
|
|
App::quit();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (msg->hwnd == wnd->psHwnd() || msg->hwnd && !wnd->psHwnd()) {
|
|
|
|
return mainWindowEvent(msg->hwnd, msg->message, msg->wParam, msg->lParam, (LRESULT*)result);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result) {
|
|
|
|
using ShadowsChange = MainWindow::ShadowsChange;
|
|
|
|
|
|
|
|
if (auto tbCreatedMsgId = Platform::MainWindow::TaskbarCreatedMsgId()) {
|
|
|
|
if (msg == tbCreatedMsgId) {
|
|
|
|
Platform::MainWindow::TaskbarCreated();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (msg) {
|
|
|
|
|
|
|
|
case WM_TIMECHANGE: {
|
2017-04-15 18:48:54 +00:00
|
|
|
if (AuthSession::Exists()) {
|
2017-08-04 14:54:32 +00:00
|
|
|
Auth().checkAutoLockIn(100);
|
2017-04-15 18:48:54 +00:00
|
|
|
}
|
2016-06-16 12:59:54 +00:00
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_WTSSESSION_CHANGE: {
|
|
|
|
if (wParam == WTS_SESSION_LOGOFF || wParam == WTS_SESSION_LOCK) {
|
|
|
|
setSessionLoggedOff(true);
|
|
|
|
} else if (wParam == WTS_SESSION_LOGON || wParam == WTS_SESSION_UNLOCK) {
|
|
|
|
setSessionLoggedOff(false);
|
|
|
|
}
|
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_DESTROY: {
|
|
|
|
App::quit();
|
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_ACTIVATE: {
|
|
|
|
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
2017-06-21 21:38:31 +00:00
|
|
|
App::wnd()->setInactivePress(true);
|
2016-06-16 12:59:54 +00:00
|
|
|
}
|
|
|
|
if (LOWORD(wParam) != WA_INACTIVE) {
|
|
|
|
App::wnd()->shadowsActivate();
|
|
|
|
} else {
|
|
|
|
App::wnd()->shadowsDeactivate();
|
|
|
|
}
|
|
|
|
if (Global::started()) {
|
|
|
|
App::wnd()->update();
|
|
|
|
}
|
|
|
|
} return false;
|
|
|
|
|
2016-07-26 12:09:40 +00:00
|
|
|
case WM_NCPAINT: {
|
|
|
|
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
|
|
|
|
if (result) *result = 0;
|
|
|
|
} return true;
|
2016-06-16 12:59:54 +00:00
|
|
|
|
|
|
|
case WM_NCCALCSIZE: {
|
|
|
|
WINDOWPLACEMENT wp;
|
|
|
|
wp.length = sizeof(WINDOWPLACEMENT);
|
|
|
|
if (GetWindowPlacement(hWnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
|
|
|
|
LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam;
|
|
|
|
LPRECT r = (wParam == TRUE) ? ¶ms->rgrc[0] : (LPRECT)lParam;
|
|
|
|
HMONITOR hMonitor = MonitorFromPoint({ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, MONITOR_DEFAULTTONEAREST);
|
|
|
|
if (hMonitor) {
|
|
|
|
MONITORINFO mi;
|
|
|
|
mi.cbSize = sizeof(mi);
|
|
|
|
if (GetMonitorInfo(hMonitor, &mi)) {
|
|
|
|
*r = mi.rcWork;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-26 12:09:40 +00:00
|
|
|
if (result) *result = 0;
|
2016-06-16 12:59:54 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case WM_NCACTIVATE: {
|
2016-07-26 12:09:40 +00:00
|
|
|
auto res = DefWindowProc(hWnd, msg, wParam, -1);
|
|
|
|
if (result) *result = res;
|
2016-06-16 12:59:54 +00:00
|
|
|
} return true;
|
|
|
|
|
|
|
|
case WM_WINDOWPOSCHANGING:
|
|
|
|
case WM_WINDOWPOSCHANGED: {
|
|
|
|
WINDOWPLACEMENT wp;
|
|
|
|
wp.length = sizeof(WINDOWPLACEMENT);
|
|
|
|
if (GetWindowPlacement(hWnd, &wp) && (wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED)) {
|
|
|
|
App::wnd()->shadowsUpdate(ShadowsChange::Hidden);
|
|
|
|
} else {
|
|
|
|
App::wnd()->shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized, (WINDOWPOS*)lParam);
|
|
|
|
}
|
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_SIZE: {
|
|
|
|
if (App::wnd()) {
|
|
|
|
if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) {
|
|
|
|
if (wParam != SIZE_RESTORED || App::wnd()->windowState() != Qt::WindowNoState) {
|
|
|
|
Qt::WindowState state = Qt::WindowNoState;
|
|
|
|
if (wParam == SIZE_MAXIMIZED) {
|
|
|
|
state = Qt::WindowMaximized;
|
|
|
|
} else if (wParam == SIZE_MINIMIZED) {
|
|
|
|
state = Qt::WindowMinimized;
|
|
|
|
}
|
|
|
|
emit App::wnd()->windowHandle()->windowStateChanged(state);
|
|
|
|
} else {
|
2016-11-04 11:14:47 +00:00
|
|
|
App::wnd()->positionUpdated();
|
2016-06-16 12:59:54 +00:00
|
|
|
}
|
|
|
|
App::wnd()->psUpdateMargins();
|
|
|
|
MainWindow::ShadowsChanges changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? ShadowsChange::Hidden : (ShadowsChange::Resized | ShadowsChange::Shown);
|
|
|
|
App::wnd()->shadowsUpdate(changes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_SHOWWINDOW: {
|
|
|
|
LONG style = GetWindowLong(hWnd, GWL_STYLE);
|
|
|
|
auto changes = ShadowsChange::Resized | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) ? ShadowsChange::Shown : ShadowsChange::Hidden);
|
|
|
|
App::wnd()->shadowsUpdate(changes);
|
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_MOVE: {
|
|
|
|
App::wnd()->shadowsUpdate(ShadowsChange::Moved);
|
2016-11-04 11:14:47 +00:00
|
|
|
App::wnd()->positionUpdated();
|
2016-06-16 12:59:54 +00:00
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_NCHITTEST: {
|
2016-07-26 12:09:40 +00:00
|
|
|
if (!result) return false;
|
|
|
|
|
2016-06-16 12:59:54 +00:00
|
|
|
POINTS p = MAKEPOINTS(lParam);
|
|
|
|
RECT r;
|
|
|
|
GetWindowRect(hWnd, &r);
|
2016-09-29 11:37:16 +00:00
|
|
|
auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
|
2016-06-16 12:59:54 +00:00
|
|
|
switch (res) {
|
2016-11-04 08:23:50 +00:00
|
|
|
case Window::HitTestResult::Client:
|
|
|
|
case Window::HitTestResult::SysButton: *result = HTCLIENT; break;
|
|
|
|
case Window::HitTestResult::Caption: *result = HTCAPTION; break;
|
|
|
|
case Window::HitTestResult::Top: *result = HTTOP; break;
|
|
|
|
case Window::HitTestResult::TopRight: *result = HTTOPRIGHT; break;
|
|
|
|
case Window::HitTestResult::Right: *result = HTRIGHT; break;
|
|
|
|
case Window::HitTestResult::BottomRight: *result = HTBOTTOMRIGHT; break;
|
|
|
|
case Window::HitTestResult::Bottom: *result = HTBOTTOM; break;
|
|
|
|
case Window::HitTestResult::BottomLeft: *result = HTBOTTOMLEFT; break;
|
|
|
|
case Window::HitTestResult::Left: *result = HTLEFT; break;
|
|
|
|
case Window::HitTestResult::TopLeft: *result = HTTOPLEFT; break;
|
|
|
|
case Window::HitTestResult::None:
|
|
|
|
default: *result = HTTRANSPARENT; break;
|
2016-06-16 12:59:54 +00:00
|
|
|
};
|
|
|
|
} return true;
|
|
|
|
|
|
|
|
case WM_NCRBUTTONUP: {
|
|
|
|
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
|
|
|
} return true;
|
|
|
|
|
|
|
|
case WM_SYSCOMMAND: {
|
|
|
|
if (wParam == SC_MOUSEMENU) {
|
|
|
|
POINTS p = MAKEPOINTS(lParam);
|
2017-05-19 14:02:55 +00:00
|
|
|
App::wnd()->updateSystemMenu(App::wnd()->windowHandle()->windowState());
|
2016-06-16 12:59:54 +00:00
|
|
|
TrackPopupMenu(App::wnd()->psMenu(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, p.x, p.y, 0, hWnd, 0);
|
|
|
|
}
|
|
|
|
} return false;
|
|
|
|
|
|
|
|
case WM_COMMAND: {
|
|
|
|
if (HIWORD(wParam)) return false;
|
|
|
|
int cmd = LOWORD(wParam);
|
|
|
|
switch (cmd) {
|
|
|
|
case SC_CLOSE: App::wnd()->close(); return true;
|
|
|
|
case SC_MINIMIZE: App::wnd()->setWindowState(Qt::WindowMinimized); return true;
|
|
|
|
case SC_MAXIMIZE: App::wnd()->setWindowState(Qt::WindowMaximized); return true;
|
|
|
|
case SC_RESTORE: App::wnd()->setWindowState(Qt::WindowNoState); return true;
|
|
|
|
}
|
|
|
|
} return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Platform
|