Updated TDesktop sources to 2.1.18 beta
This commit is contained in:
commit
d920a689e3
45 changed files with 465 additions and 758 deletions
|
|
@ -338,6 +338,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_update_fail" = "Update check failed :(";
|
"lng_settings_update_fail" = "Update check failed :(";
|
||||||
"lng_settings_workmode_tray" = "Show tray icon";
|
"lng_settings_workmode_tray" = "Show tray icon";
|
||||||
"lng_settings_workmode_window" = "Show taskbar icon";
|
"lng_settings_workmode_window" = "Show taskbar icon";
|
||||||
|
"lng_settings_native_frame" = "Use system window frame";
|
||||||
"lng_settings_auto_start" = "Launch Telegram when system starts";
|
"lng_settings_auto_start" = "Launch Telegram when system starts";
|
||||||
"lng_settings_start_min" = "Launch minimized";
|
"lng_settings_start_min" = "Launch minimized";
|
||||||
"lng_settings_add_sendto" = "Place Telegram in \"Send to\" menu";
|
"lng_settings_add_sendto" = "Place Telegram in \"Send to\" menu";
|
||||||
|
|
@ -2444,7 +2445,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"ktg_net_speed_boost_big" = "Big";
|
"ktg_net_speed_boost_big" = "Big";
|
||||||
|
|
||||||
"ktg_settings_system" = "System";
|
"ktg_settings_system" = "System";
|
||||||
"ktg_settings_use_native_decorations" = "Native window decorations";
|
|
||||||
|
|
||||||
"ktg_settings_other" = "Other";
|
"ktg_settings_other" = "Other";
|
||||||
"ktg_profile_copy_id" = "Copy ID";
|
"ktg_profile_copy_id" = "Copy ID";
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
"ktg_net_speed_boost_medium": "Medium",
|
"ktg_net_speed_boost_medium": "Medium",
|
||||||
"ktg_net_speed_boost_big": "Big",
|
"ktg_net_speed_boost_big": "Big",
|
||||||
"ktg_settings_system": "System",
|
"ktg_settings_system": "System",
|
||||||
"ktg_settings_use_native_decorations": "Native window decorations",
|
|
||||||
"ktg_settings_other": "Other",
|
"ktg_settings_other": "Other",
|
||||||
"ktg_profile_copy_id": "Copy ID",
|
"ktg_profile_copy_id": "Copy ID",
|
||||||
"ktg_profile_bot_id": "Bot ID",
|
"ktg_profile_bot_id": "Bot ID",
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
"ktg_net_speed_boost_medium": "Średnie",
|
"ktg_net_speed_boost_medium": "Średnie",
|
||||||
"ktg_net_speed_boost_big": "Duże",
|
"ktg_net_speed_boost_big": "Duże",
|
||||||
"ktg_settings_system": "System",
|
"ktg_settings_system": "System",
|
||||||
"ktg_settings_use_native_decorations": "Natywne dekoracje okna",
|
|
||||||
"ktg_settings_other": "Inne",
|
"ktg_settings_other": "Inne",
|
||||||
"ktg_profile_copy_id": "Kopiuj ID",
|
"ktg_profile_copy_id": "Kopiuj ID",
|
||||||
"ktg_profile_bot_id": "ID Bota",
|
"ktg_profile_bot_id": "ID Bota",
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@
|
||||||
"ktg_net_speed_boost_medium": "Среднее",
|
"ktg_net_speed_boost_medium": "Среднее",
|
||||||
"ktg_net_speed_boost_big": "Высокое",
|
"ktg_net_speed_boost_big": "Высокое",
|
||||||
"ktg_settings_system": "Система",
|
"ktg_settings_system": "Система",
|
||||||
"ktg_settings_use_native_decorations": "Системная рамка окна",
|
|
||||||
"ktg_settings_other": "Прочие",
|
"ktg_settings_other": "Прочие",
|
||||||
"ktg_profile_copy_id": "Копировать ID",
|
"ktg_profile_copy_id": "Копировать ID",
|
||||||
"ktg_profile_bot_id": "ID бота",
|
"ktg_profile_bot_id": "ID бота",
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
"ktg_net_speed_boost_medium": "orta",
|
"ktg_net_speed_boost_medium": "orta",
|
||||||
"ktg_net_speed_boost_big": "Güçlü",
|
"ktg_net_speed_boost_big": "Güçlü",
|
||||||
"ktg_settings_system": "sistem",
|
"ktg_settings_system": "sistem",
|
||||||
"ktg_settings_use_native_decorations": "Yerel pencere süslemeleri",
|
|
||||||
"ktg_settings_other": "Başka",
|
"ktg_settings_other": "Başka",
|
||||||
"ktg_profile_copy_id": "ID kopyala",
|
"ktg_profile_copy_id": "ID kopyala",
|
||||||
"ktg_profile_bot_id": "Bot ID",
|
"ktg_profile_bot_id": "Bot ID",
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@
|
||||||
"ktg_net_speed_boost_medium": "Середнє",
|
"ktg_net_speed_boost_medium": "Середнє",
|
||||||
"ktg_net_speed_boost_big": "Високе",
|
"ktg_net_speed_boost_big": "Високе",
|
||||||
"ktg_settings_system": "Система",
|
"ktg_settings_system": "Система",
|
||||||
"ktg_settings_use_native_decorations": "Системна рамка вікна",
|
|
||||||
"ktg_settings_other": "Інші",
|
"ktg_settings_other": "Інші",
|
||||||
"ktg_profile_copy_id": "Копіювати ID",
|
"ktg_profile_copy_id": "Копіювати ID",
|
||||||
"ktg_profile_bot_id": "ID бота",
|
"ktg_profile_bot_id": "ID бота",
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||||
ProcessorArchitecture="ARCHITECTURE"
|
ProcessorArchitecture="ARCHITECTURE"
|
||||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||||
Version="2.1.17.0" />
|
Version="2.1.18.0" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>Telegram Desktop</DisplayName>
|
<DisplayName>Telegram Desktop</DisplayName>
|
||||||
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>
|
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,1,17,0
|
FILEVERSION 2,1,18,0
|
||||||
PRODUCTVERSION 2,1,17,0
|
PRODUCTVERSION 2,1,18,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
|
@ -62,10 +62,10 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||||
VALUE "FileDescription", "Telegram Desktop"
|
VALUE "FileDescription", "Telegram Desktop"
|
||||||
VALUE "FileVersion", "2.1.17.0"
|
VALUE "FileVersion", "2.1.18.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "2.1.17.0"
|
VALUE "ProductVersion", "2.1.18.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,1,17,0
|
FILEVERSION 2,1,18,0
|
||||||
PRODUCTVERSION 2,1,17,0
|
PRODUCTVERSION 2,1,18,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
|
@ -53,10 +53,10 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||||
VALUE "FileVersion", "2.1.17.0"
|
VALUE "FileVersion", "2.1.18.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "2.1.17.0"
|
VALUE "ProductVersion", "2.1.18.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,6 @@ namespace App {
|
||||||
void setLaunchState(LaunchState state);
|
void setLaunchState(LaunchState state);
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
constexpr auto kFileSizeLimit = 1500 * 1024 * 1024; // Load files up to 1500mb
|
|
||||||
constexpr auto kImageSizeLimit = 64 * 1024 * 1024; // Open images up to 64mb jpg/png/gif
|
constexpr auto kImageSizeLimit = 64 * 1024 * 1024; // Open images up to 64mb jpg/png/gif
|
||||||
QImage readImage(QByteArray data, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr);
|
QImage readImage(QByteArray data, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr);
|
||||||
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
|
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,17 @@ std::map<int, const char*> BetaLogs() {
|
||||||
"- Fix high definition GIF animations opening in media viewer.\n"
|
"- Fix high definition GIF animations opening in media viewer.\n"
|
||||||
|
|
||||||
"- Multiple crash fixes."
|
"- Multiple crash fixes."
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
2001018,
|
||||||
|
"- Fix a possible crash in Picture-in-Picture video player.\n"
|
||||||
|
|
||||||
|
"- Fix copying links from message texts.\n"
|
||||||
|
|
||||||
|
"- Raise file size limit to 2000 MB.\n"
|
||||||
|
|
||||||
|
"- Allow using system window frame in Windows and Linux."
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,8 @@ QByteArray Settings::serialize() const {
|
||||||
1000000))
|
1000000))
|
||||||
<< qint32(_thirdColumnWidth.current())
|
<< qint32(_thirdColumnWidth.current())
|
||||||
<< qint32(_thirdSectionExtendedBy)
|
<< qint32(_thirdSectionExtendedBy)
|
||||||
<< qint32(_notifyFromAll ? 1 : 0);
|
<< qint32(_notifyFromAll ? 1 : 0)
|
||||||
|
<< qint32(_nativeWindowFrame.current() ? 1 : 0);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -169,6 +170,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
qint32 thirdColumnWidth = _thirdColumnWidth.current();
|
qint32 thirdColumnWidth = _thirdColumnWidth.current();
|
||||||
qint32 thirdSectionExtendedBy = _thirdSectionExtendedBy;
|
qint32 thirdSectionExtendedBy = _thirdSectionExtendedBy;
|
||||||
qint32 notifyFromAll = _notifyFromAll ? 1 : 0;
|
qint32 notifyFromAll = _notifyFromAll ? 1 : 0;
|
||||||
|
qint32 nativeWindowFrame = _nativeWindowFrame.current() ? 1 : 0;
|
||||||
|
|
||||||
stream >> themesAccentColors;
|
stream >> themesAccentColors;
|
||||||
if (!stream.atEnd()) {
|
if (!stream.atEnd()) {
|
||||||
|
|
@ -243,6 +245,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
>> notifyFromAll;
|
>> notifyFromAll;
|
||||||
dialogsWidthRatio = snap(dialogsWidthRatioInt / 1000000., 0., 1.);
|
dialogsWidthRatio = snap(dialogsWidthRatioInt / 1000000., 0., 1.);
|
||||||
}
|
}
|
||||||
|
if (!stream.atEnd()) {
|
||||||
|
stream >> nativeWindowFrame;
|
||||||
|
}
|
||||||
if (stream.status() != QDataStream::Ok) {
|
if (stream.status() != QDataStream::Ok) {
|
||||||
LOG(("App Error: "
|
LOG(("App Error: "
|
||||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||||
|
|
@ -335,6 +340,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
_tabbedSelectorSectionEnabled = false;
|
_tabbedSelectorSectionEnabled = false;
|
||||||
}
|
}
|
||||||
_notifyFromAll = (notifyFromAll == 1);
|
_notifyFromAll = (notifyFromAll == 1);
|
||||||
|
_nativeWindowFrame = (nativeWindowFrame == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::chatWide() const {
|
bool Settings::chatWide() const {
|
||||||
|
|
|
||||||
|
|
@ -407,6 +407,15 @@ public:
|
||||||
[[nodiscard]] bool notifyFromAll() const {
|
[[nodiscard]] bool notifyFromAll() const {
|
||||||
return _notifyFromAll;
|
return _notifyFromAll;
|
||||||
}
|
}
|
||||||
|
void setNativeWindowFrame(bool value) {
|
||||||
|
_nativeWindowFrame = value;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool nativeWindowFrame() const {
|
||||||
|
return _nativeWindowFrame.current();
|
||||||
|
}
|
||||||
|
[[nodiscard]] rpl::producer<bool> nativeWindowFrameChanges() const {
|
||||||
|
return _nativeWindowFrame.changes();
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static bool ThirdColumnByDefault();
|
[[nodiscard]] static bool ThirdColumnByDefault();
|
||||||
[[nodiscard]] float64 DefaultDialogsWidthRatio();
|
[[nodiscard]] float64 DefaultDialogsWidthRatio();
|
||||||
|
|
@ -474,6 +483,7 @@ private:
|
||||||
rpl::variable<float64> _dialogsWidthRatio; // per-window
|
rpl::variable<float64> _dialogsWidthRatio; // per-window
|
||||||
rpl::variable<int> _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
|
rpl::variable<int> _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
|
||||||
bool _notifyFromAll = true;
|
bool _notifyFromAll = true;
|
||||||
|
rpl::variable<bool> _nativeWindowFrame = false;
|
||||||
|
|
||||||
bool _tabbedReplacedWithInfo = false; // per-window
|
bool _tabbedReplacedWithInfo = false; // per-window
|
||||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
|
||||||
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
|
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
|
||||||
constexpr auto AppName = "Kotatogram Desktop"_cs;
|
constexpr auto AppName = "Kotatogram Desktop"_cs;
|
||||||
constexpr auto AppFile = "Kotatogram"_cs;
|
constexpr auto AppFile = "Kotatogram"_cs;
|
||||||
constexpr auto AppVersion = 2001017;
|
constexpr auto AppVersion = 2001018;
|
||||||
constexpr auto AppVersionStr = "2.1.17";
|
constexpr auto AppVersionStr = "2.1.18";
|
||||||
constexpr auto AppBetaVersion = true;
|
constexpr auto AppBetaVersion = true;
|
||||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Data {
|
namespace Data {
|
||||||
namespace AutoDownload {
|
namespace AutoDownload {
|
||||||
|
|
||||||
constexpr auto kMaxBytesLimit = 3000 * 512 * 1024;
|
constexpr auto kMaxBytesLimit = 4000 * 512 * 1024;
|
||||||
|
|
||||||
enum class Source {
|
enum class Source {
|
||||||
User = 0x00,
|
User = 0x00,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ constexpr auto kFileNextRequestDelay = crl::time(20);
|
||||||
constexpr auto kChatsSliceLimit = 100;
|
constexpr auto kChatsSliceLimit = 100;
|
||||||
constexpr auto kMessagesSliceLimit = 100;
|
constexpr auto kMessagesSliceLimit = 100;
|
||||||
constexpr auto kTopPeerSliceLimit = 100;
|
constexpr auto kTopPeerSliceLimit = 100;
|
||||||
constexpr auto kFileMaxSize = 1500 * 1024 * 1024;
|
constexpr auto kFileMaxSize = 2000 * 1024 * 1024;
|
||||||
constexpr auto kLocationCacheSize = 100'000;
|
constexpr auto kLocationCacheSize = 100'000;
|
||||||
|
|
||||||
struct LocationKey {
|
struct LocationKey {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Export {
|
namespace Export {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kMaxFileSize = 1500 * 1024 * 1024;
|
constexpr auto kMaxFileSize = 2000 * 1024 * 1024;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,21 +88,18 @@ int SizeLimitByIndex(int index) {
|
||||||
const auto megabytes = [&] {
|
const auto megabytes = [&] {
|
||||||
if (index <= 10) {
|
if (index <= 10) {
|
||||||
return index;
|
return index;
|
||||||
}
|
} else if (index <= 30) {
|
||||||
else if (index <= 30) {
|
|
||||||
return 10 + (index - 10) * 2;
|
return 10 + (index - 10) * 2;
|
||||||
}
|
} else if (index <= 40) {
|
||||||
else if (index <= 40) {
|
|
||||||
return 50 + (index - 30) * 5;
|
return 50 + (index - 30) * 5;
|
||||||
}
|
} else if (index <= 60) {
|
||||||
else if (index <= 60) {
|
|
||||||
return 100 + (index - 40) * 10;
|
return 100 + (index - 40) * 10;
|
||||||
}
|
} else if (index <= 70) {
|
||||||
else if (index <= 70) {
|
|
||||||
return 300 + (index - 60) * 20;
|
return 300 + (index - 60) * 20;
|
||||||
}
|
} else if (index <= 80) {
|
||||||
else {
|
return 500 + (index - 70) * 50;
|
||||||
return 500 + (index - 70) * 100;
|
} else {
|
||||||
|
return 1000 + (index - 80) * 100;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
return megabytes * kMegabyte;
|
return megabytes * kMegabyte;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class Session;
|
||||||
namespace Export {
|
namespace Export {
|
||||||
namespace View {
|
namespace View {
|
||||||
|
|
||||||
constexpr auto kSizeValueCount = 80;
|
constexpr auto kSizeValueCount = 90;
|
||||||
int SizeLimitByIndex(int index);
|
int SizeLimitByIndex(int index);
|
||||||
|
|
||||||
class SettingsWidget : public Ui::RpWidget {
|
class SettingsWidget : public Ui::RpWidget {
|
||||||
|
|
|
||||||
|
|
@ -437,12 +437,12 @@ void SetupKotatoSystem(
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
AddSubsectionTitle(container, tr::ktg_settings_system());
|
AddSubsectionTitle(container, tr::ktg_settings_system());
|
||||||
|
|
||||||
#if defined Q_OS_WIN || defined Q_OS_MAC || QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
#if defined Q_OS_MAC
|
||||||
const auto useNativeDecorationsToggled = Ui::CreateChild<rpl::event_stream<bool>>(
|
const auto useNativeDecorationsToggled = Ui::CreateChild<rpl::event_stream<bool>>(
|
||||||
container.get());
|
container.get());
|
||||||
AddButton(
|
AddButton(
|
||||||
container,
|
container,
|
||||||
tr::ktg_settings_use_native_decorations(),
|
tr::lng_settings_native_frame(),
|
||||||
st::settingsButton
|
st::settingsButton
|
||||||
)->toggleOn(
|
)->toggleOn(
|
||||||
useNativeDecorationsToggled->events_starting_with_copy(cUseNativeDecorations())
|
useNativeDecorationsToggled->events_starting_with_copy(cUseNativeDecorations())
|
||||||
|
|
@ -464,7 +464,7 @@ void SetupKotatoSystem(
|
||||||
confirmed,
|
confirmed,
|
||||||
cancelled));
|
cancelled));
|
||||||
}, container->lifetime());
|
}, container->lifetime());
|
||||||
#endif // Q_OS_WIN || Q_OS_MAC || Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
AddButton(
|
AddButton(
|
||||||
container,
|
container,
|
||||||
|
|
|
||||||
|
|
@ -2185,13 +2185,19 @@ void MainWidget::updateControlsGeometry() {
|
||||||
auto mainSectionWidth = width() - dialogsWidth - thirdSectionWidth;
|
auto mainSectionWidth = width() - dialogsWidth - thirdSectionWidth;
|
||||||
|
|
||||||
_dialogs->setGeometryWithTopMoved({ 0, 0, dialogsWidth, height() }, _contentScrollAddToY);
|
_dialogs->setGeometryWithTopMoved({ 0, 0, dialogsWidth, height() }, _contentScrollAddToY);
|
||||||
_sideShadow->setGeometryToLeft(dialogsWidth, 0, st::lineWidth, height());
|
const auto shadowTop = _controller->window().verticalShadowTop();
|
||||||
|
const auto shadowHeight = height() - shadowTop;
|
||||||
|
_sideShadow->setGeometryToLeft(
|
||||||
|
dialogsWidth,
|
||||||
|
shadowTop,
|
||||||
|
st::lineWidth,
|
||||||
|
shadowHeight);
|
||||||
if (_thirdShadow) {
|
if (_thirdShadow) {
|
||||||
_thirdShadow->setGeometryToLeft(
|
_thirdShadow->setGeometryToLeft(
|
||||||
width() - thirdSectionWidth - st::lineWidth,
|
width() - thirdSectionWidth - st::lineWidth,
|
||||||
0,
|
shadowTop,
|
||||||
st::lineWidth,
|
st::lineWidth,
|
||||||
height());
|
shadowHeight);
|
||||||
}
|
}
|
||||||
if (_callTopBar) {
|
if (_callTopBar) {
|
||||||
_callTopBar->resizeToWidth(mainSectionWidth);
|
_callTopBar->resizeToWidth(mainSectionWidth);
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,6 @@ public:
|
||||||
|
|
||||||
void checkHistoryActivation();
|
void checkHistoryActivation();
|
||||||
|
|
||||||
void fixOrder();
|
|
||||||
|
|
||||||
void sendPaths();
|
void sendPaths();
|
||||||
|
|
||||||
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
|
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
|
||||||
|
|
@ -79,6 +77,7 @@ public:
|
||||||
|
|
||||||
void showMainMenu();
|
void showMainMenu();
|
||||||
void updateTrayMenu(bool force = false) override;
|
void updateTrayMenu(bool force = false) override;
|
||||||
|
void fixOrder() override;
|
||||||
|
|
||||||
void showSpecialLayer(
|
void showSpecialLayer(
|
||||||
object_ptr<Ui::LayerWidget> layer,
|
object_ptr<Ui::LayerWidget> layer,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Streaming {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// This is the maximum file size in Telegram API.
|
// This is the maximum file size in Telegram API.
|
||||||
constexpr auto kMaxFileSize = 3000 * 512 * 1024;
|
constexpr auto kMaxFileSize = 4000 * 512 * 1024;
|
||||||
|
|
||||||
int ValidateLocalSize(int64 size) {
|
int ValidateLocalSize(int64 size) {
|
||||||
return (size > 0 && size <= kMaxFileSize) ? int(size) : 0;
|
return (size > 0 && size <= kMaxFileSize) ? int(size) : 0;
|
||||||
|
|
|
||||||
|
|
@ -598,6 +598,7 @@ void PipPanel::mousePressEvent(QMouseEvent *e) {
|
||||||
if (e->button() != Qt::LeftButton) {
|
if (e->button() != Qt::LeftButton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
updateOverState(e->pos());
|
||||||
_pressState = _overState;
|
_pressState = _overState;
|
||||||
_pressPoint = e->globalPos();
|
_pressPoint = e->globalPos();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,22 @@ void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palet
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
||||||
if (!DesktopEnvironment::IsUnity()) {
|
return !DesktopEnvironment::IsUnity();
|
||||||
return object_ptr<Window::TitleWidgetQt>(parent);
|
#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
}
|
return false;
|
||||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
|
}
|
||||||
|
|
||||||
return { nullptr };
|
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
||||||
|
return AllowNativeWindowFrameToggle()
|
||||||
|
? object_ptr<Window::TitleWidgetQt>(parent)
|
||||||
|
: object_ptr<Window::TitleWidgetQt>{ nullptr };
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int PreviewTitleHeight() {
|
inline int PreviewTitleHeight() {
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,16 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
||||||
|
|
||||||
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int PreviewTitleHeight();
|
int PreviewTitleHeight();
|
||||||
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
|
bool AllowNativeWindowFrameToggle();
|
||||||
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
||||||
|
bool NativeTitleRequiresShadow();
|
||||||
|
|
||||||
int PreviewTitleHeight();
|
int PreviewTitleHeight();
|
||||||
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
||||||
|
|
@ -33,12 +35,22 @@ void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRe
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
||||||
return object_ptr<Window::TitleWidgetQt>(parent);
|
return true;
|
||||||
|
#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
|
return false;
|
||||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
|
}
|
||||||
|
|
||||||
return { nullptr };
|
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
||||||
|
return AllowNativeWindowFrameToggle()
|
||||||
|
? object_ptr<Window::TitleWidgetQt>(parent)
|
||||||
|
: object_ptr<Window::TitleWidgetQt>{ nullptr };
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int PreviewTitleHeight() {
|
inline int PreviewTitleHeight() {
|
||||||
|
|
|
||||||
|
|
@ -38,28 +38,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include <Windowsx.h>
|
#include <Windowsx.h>
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
#define max(a, b) ((a) < (b) ? (b) : (a))
|
|
||||||
#include <gdiplus.h>
|
|
||||||
#undef min
|
|
||||||
#undef max
|
|
||||||
|
|
||||||
// WM_POINTER support from Windows 8 onwards (WINVER >= 0x0602)
|
|
||||||
#ifndef WM_POINTERUPDATE
|
|
||||||
# define WM_NCPOINTERUPDATE 0x0241
|
|
||||||
# define WM_NCPOINTERDOWN 0x0242
|
|
||||||
# define WM_NCPOINTERUP 0x0243
|
|
||||||
# define WM_POINTERUPDATE 0x0245
|
|
||||||
# define WM_POINTERDOWN 0x0246
|
|
||||||
# define WM_POINTERUP 0x0247
|
|
||||||
# define WM_POINTERENTER 0x0249
|
|
||||||
# define WM_POINTERLEAVE 0x024A
|
|
||||||
# define WM_POINTERACTIVATE 0x024B
|
|
||||||
# define WM_POINTERCAPTURECHANGED 0x024C
|
|
||||||
# define WM_POINTERWHEEL 0x024E
|
|
||||||
# define WM_POINTERHWHEEL 0x024F
|
|
||||||
#endif // WM_POINTERUPDATE
|
|
||||||
|
|
||||||
HICON qt_pixmapToWinHICON(const QPixmap &);
|
HICON qt_pixmapToWinHICON(const QPixmap &);
|
||||||
|
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
|
|
@ -112,515 +90,6 @@ HWND createTaskbarHider() {
|
||||||
return hWnd;
|
return hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
|
||||||
_PsInitHor = 0x01,
|
|
||||||
_PsInitVer = 0x02,
|
|
||||||
};
|
|
||||||
|
|
||||||
int32 _psSize = 0;
|
|
||||||
class _PsShadowWindows {
|
|
||||||
public:
|
|
||||||
|
|
||||||
using Change = MainWindow::ShadowsChange;
|
|
||||||
using Changes = MainWindow::ShadowsChanges;
|
|
||||||
|
|
||||||
_PsShadowWindows() : screenDC(0), noKeyColor(RGB(255, 255, 255)) {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
dcs[i] = 0;
|
|
||||||
bitmaps[i] = 0;
|
|
||||||
hwnds[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setColor(QColor c) {
|
|
||||||
r = c.red();
|
|
||||||
g = c.green();
|
|
||||||
b = c.blue();
|
|
||||||
|
|
||||||
if (!hwnds[0]) return;
|
|
||||||
Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b));
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
Gdiplus::Graphics graphics(dcs[i]);
|
|
||||||
graphics.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
if ((i % 2) && _h || !(i % 2) && _w) {
|
|
||||||
graphics.FillRectangle(&brush, 0, 0, (i % 2) ? _size : _w, (i % 2) ? _h : _size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
initCorners();
|
|
||||||
|
|
||||||
_x = _y = _w = _h = 0;
|
|
||||||
update(Change::Moved | Change::Resized);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool init(not_null<MainWindow*> window, QColor c) {
|
|
||||||
_window = window;
|
|
||||||
_fullsize = st::windowShadow.width();
|
|
||||||
_shift = st::windowShadowShift;
|
|
||||||
auto cornersImage = QImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
{
|
|
||||||
Painter p(&cornersImage);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
st::windowShadow.paint(p, 0, 0, _fullsize, QColor(0, 0, 0));
|
|
||||||
}
|
|
||||||
if (rtl()) cornersImage = cornersImage.mirrored(true, false);
|
|
||||||
|
|
||||||
_metaSize = _fullsize + 2 * _shift;
|
|
||||||
_alphas.reserve(_metaSize);
|
|
||||||
_colors.reserve(_metaSize * _metaSize);
|
|
||||||
for (int32 j = 0; j < _metaSize; ++j) {
|
|
||||||
for (int32 i = 0; i < _metaSize; ++i) {
|
|
||||||
_colors.push_back((i < 2 * _shift || j < 2 * _shift) ? 1 : qMax(BYTE(1), BYTE(cornersImage.pixel(QPoint(i - 2 * _shift, j - 2 * _shift)) >> 24)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uchar prev = 0;
|
|
||||||
for (int32 i = 0; i < _metaSize; ++i) {
|
|
||||||
uchar a = _colors[(_metaSize - 1) * _metaSize + i];
|
|
||||||
if (a < prev) break;
|
|
||||||
|
|
||||||
_alphas.push_back(a);
|
|
||||||
prev = a;
|
|
||||||
}
|
|
||||||
_psSize = _size = _alphas.size() - 2 * _shift;
|
|
||||||
|
|
||||||
setColor(c);
|
|
||||||
|
|
||||||
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
|
|
||||||
ULONG_PTR gdiplusToken;
|
|
||||||
Gdiplus::Status gdiRes = Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
|
|
||||||
|
|
||||||
if (gdiRes != Gdiplus::Ok) {
|
|
||||||
LOG(("Application Error: could not init GDI+, error: %1").arg((int)gdiRes));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
blend.AlphaFormat = AC_SRC_ALPHA;
|
|
||||||
blend.SourceConstantAlpha = 255;
|
|
||||||
blend.BlendFlags = 0;
|
|
||||||
blend.BlendOp = AC_SRC_OVER;
|
|
||||||
|
|
||||||
screenDC = GetDC(0);
|
|
||||||
if (!screenDC) {
|
|
||||||
LOG(("Application Error: could not GetDC(0), error: %2").arg(GetLastError()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto avail = QApplication::desktop()->availableGeometry();
|
|
||||||
max_w = avail.width();
|
|
||||||
accumulate_max(max_w, st::windowMinWidth);
|
|
||||||
max_h = avail.height();
|
|
||||||
accumulate_max(max_h, st::defaultWindowTitle.height + st::windowMinHeight);
|
|
||||||
|
|
||||||
HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
|
|
||||||
HWND hwnd = _window ? _window->psHwnd() : nullptr;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
QString cn = QString("KotatogramShadow%1").arg(i);
|
|
||||||
LPCWSTR _cn = (LPCWSTR)cn.utf16();
|
|
||||||
WNDCLASSEX wc;
|
|
||||||
|
|
||||||
wc.cbSize = sizeof(wc);
|
|
||||||
wc.style = 0;
|
|
||||||
wc.lpfnWndProc = wndProc;
|
|
||||||
wc.cbClsExtra = 0;
|
|
||||||
wc.cbWndExtra = 0;
|
|
||||||
wc.hInstance = appinst;
|
|
||||||
wc.hIcon = 0;
|
|
||||||
wc.hCursor = 0;
|
|
||||||
wc.hbrBackground = 0;
|
|
||||||
wc.lpszMenuName = NULL;
|
|
||||||
wc.lpszClassName = _cn;
|
|
||||||
wc.hIconSm = 0;
|
|
||||||
if (!RegisterClassEx(&wc)) {
|
|
||||||
LOG(("Application Error: could not register shadow window class %1, error: %2").arg(i).arg(GetLastError()));
|
|
||||||
destroy();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hwnds[i] = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, _cn, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, appinst, 0);
|
|
||||||
if (!hwnds[i]) {
|
|
||||||
LOG(("Application Error: could not create shadow window class %1, error: %2").arg(i).arg(GetLastError()));
|
|
||||||
destroy();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SetWindowLongPtr(hwnds[i], GWLP_HWNDPARENT, (LONG)hwnd);
|
|
||||||
|
|
||||||
dcs[i] = CreateCompatibleDC(screenDC);
|
|
||||||
if (!dcs[i]) {
|
|
||||||
LOG(("Application Error: could not create dc for shadow window class %1, error: %2").arg(i).arg(GetLastError()));
|
|
||||||
destroy();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmaps[i] = CreateCompatibleBitmap(screenDC, (i % 2) ? _size : max_w, (i % 2) ? max_h : _size);
|
|
||||||
if (!bitmaps[i]) {
|
|
||||||
LOG(("Application Error: could not create bitmap for shadow window class %1, error: %2").arg(i).arg(GetLastError()));
|
|
||||||
destroy();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectObject(dcs[i], bitmaps[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList alphasForLog;
|
|
||||||
for_const (auto alpha, _alphas) {
|
|
||||||
alphasForLog.append(QString::number(alpha));
|
|
||||||
}
|
|
||||||
LOG(("Window Shadow: %1").arg(alphasForLog.join(", ")));
|
|
||||||
|
|
||||||
initCorners();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initCorners(int directions = (_PsInitHor | _PsInitVer)) {
|
|
||||||
bool hor = (directions & _PsInitHor), ver = (directions & _PsInitVer);
|
|
||||||
Gdiplus::Graphics graphics0(dcs[0]), graphics1(dcs[1]), graphics2(dcs[2]), graphics3(dcs[3]);
|
|
||||||
graphics0.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
graphics1.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
graphics2.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
graphics3.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
|
|
||||||
Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b));
|
|
||||||
if (hor) graphics0.FillRectangle(&brush, 0, 0, _fullsize - (_size - _shift), 2 * _shift);
|
|
||||||
|
|
||||||
if (ver) {
|
|
||||||
graphics1.FillRectangle(&brush, 0, 0, _size, 2 * _shift);
|
|
||||||
graphics3.FillRectangle(&brush, 0, 0, _size, 2 * _shift);
|
|
||||||
graphics1.FillRectangle(&brush, _size - _shift, 2 * _shift, _shift, _fullsize);
|
|
||||||
graphics3.FillRectangle(&brush, 0, 2 * _shift, _shift, _fullsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hor) {
|
|
||||||
for (int j = 2 * _shift; j < _size; ++j) {
|
|
||||||
for (int k = 0; k < _fullsize - (_size - _shift); ++k) {
|
|
||||||
brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b));
|
|
||||||
graphics0.FillRectangle(&brush, k, j, 1, 1);
|
|
||||||
graphics2.FillRectangle(&brush, k, _size - (j - 2 * _shift) - 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j = _size; j < _size + 2 * _shift; ++j) {
|
|
||||||
for (int k = 0; k < _fullsize - (_size - _shift); ++k) {
|
|
||||||
brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b));
|
|
||||||
graphics2.FillRectangle(&brush, k, _size - (j - 2 * _shift) - 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ver) {
|
|
||||||
for (int j = 2 * _shift; j < _fullsize + 2 * _shift; ++j) {
|
|
||||||
for (int k = _shift; k < _size; ++k) {
|
|
||||||
brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + (k + _shift)], r, g, b));
|
|
||||||
graphics1.FillRectangle(&brush, _size - k - 1, j, 1, 1);
|
|
||||||
graphics3.FillRectangle(&brush, k, j, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void verCorners(int h, Gdiplus::Graphics *pgraphics1, Gdiplus::Graphics *pgraphics3) {
|
|
||||||
Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b));
|
|
||||||
pgraphics1->FillRectangle(&brush, _size - _shift, h - _fullsize, _shift, _fullsize);
|
|
||||||
pgraphics3->FillRectangle(&brush, 0, h - _fullsize, _shift, _fullsize);
|
|
||||||
for (int j = 0; j < _fullsize; ++j) {
|
|
||||||
for (int k = _shift; k < _size; ++k) {
|
|
||||||
brush.SetColor(Gdiplus::Color(_colors[(j + 2 * _shift) * _metaSize + k + _shift], r, g, b));
|
|
||||||
pgraphics1->FillRectangle(&brush, _size - k - 1, h - j - 1, 1, 1);
|
|
||||||
pgraphics3->FillRectangle(&brush, k, h - j - 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void horCorners(int w, Gdiplus::Graphics *pgraphics0, Gdiplus::Graphics *pgraphics2) {
|
|
||||||
Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b));
|
|
||||||
pgraphics0->FillRectangle(&brush, w - 2 * _size - (_fullsize - (_size - _shift)), 0, _fullsize - (_size - _shift), 2 * _shift);
|
|
||||||
for (int j = 2 * _shift; j < _size; ++j) {
|
|
||||||
for (int k = 0; k < _fullsize - (_size - _shift); ++k) {
|
|
||||||
brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b));
|
|
||||||
pgraphics0->FillRectangle(&brush, w - 2 * _size - k - 1, j, 1, 1);
|
|
||||||
pgraphics2->FillRectangle(&brush, w - 2 * _size - k - 1, _size - (j - 2 * _shift) - 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j = _size; j < _size + 2 * _shift; ++j) {
|
|
||||||
for (int k = 0; k < _fullsize - (_size - _shift); ++k) {
|
|
||||||
brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b));
|
|
||||||
pgraphics2->FillRectangle(&brush, w - 2 * _size - k - 1, _size - (j - 2 * _shift) - 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(Changes changes, WINDOWPOS *pos = 0) {
|
|
||||||
HWND hwnd = _window ? _window->psHwnd() : 0;
|
|
||||||
if (!hwnd || !hwnds[0]) return;
|
|
||||||
|
|
||||||
if (changes == Changes(Change::Activate)) {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
SetWindowPos(hwnds[i], hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changes & Change::Hidden) {
|
|
||||||
if (!hidden) {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
hidden = true;
|
|
||||||
ShowWindow(hwnds[i], SW_HIDE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_window->positionInited()) return;
|
|
||||||
|
|
||||||
int x = _x, y = _y, w = _w, h = _h;
|
|
||||||
if (pos && (!(pos->flags & SWP_NOMOVE) || !(pos->flags & SWP_NOSIZE) || !(pos->flags & SWP_NOREPOSITION))) {
|
|
||||||
if (!(pos->flags & SWP_NOMOVE)) {
|
|
||||||
x = pos->x - _size;
|
|
||||||
y = pos->y - _size;
|
|
||||||
} else if (pos->flags & SWP_NOSIZE) {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
SetWindowPos(hwnds[i], hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(pos->flags & SWP_NOSIZE)) {
|
|
||||||
w = pos->cx + 2 * _size;
|
|
||||||
h = pos->cy + 2 * _size;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
RECT r;
|
|
||||||
GetWindowRect(hwnd, &r);
|
|
||||||
x = r.left - _size;
|
|
||||||
y = r.top - _size;
|
|
||||||
w = r.right + _size - x;
|
|
||||||
h = r.bottom + _size - y;
|
|
||||||
}
|
|
||||||
if (h < 2 * _fullsize + 2 * _shift) {
|
|
||||||
h = 2 * _fullsize + 2 * _shift;
|
|
||||||
}
|
|
||||||
if (w < 2 * (_fullsize + _shift)) {
|
|
||||||
w = 2 * (_fullsize + _shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w != _w) {
|
|
||||||
int from = (_w > 2 * (_fullsize + _shift)) ? (_w - _size - _fullsize - _shift) : (_fullsize - (_size - _shift));
|
|
||||||
int to = w - _size - _fullsize - _shift;
|
|
||||||
if (w > max_w) {
|
|
||||||
from = _fullsize - (_size - _shift);
|
|
||||||
max_w *= 2;
|
|
||||||
for (int i = 0; i < 4; i += 2) {
|
|
||||||
DeleteObject(bitmaps[i]);
|
|
||||||
bitmaps[i] = CreateCompatibleBitmap(screenDC, max_w, _size);
|
|
||||||
SelectObject(dcs[i], bitmaps[i]);
|
|
||||||
}
|
|
||||||
initCorners(_PsInitHor);
|
|
||||||
}
|
|
||||||
Gdiplus::Graphics graphics0(dcs[0]), graphics2(dcs[2]);
|
|
||||||
graphics0.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
graphics2.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b));
|
|
||||||
if (to > from) {
|
|
||||||
graphics0.FillRectangle(&brush, from, 0, to - from, 2 * _shift);
|
|
||||||
for (int i = 2 * _shift; i < _size; ++i) {
|
|
||||||
Gdiplus::Pen pen(Gdiplus::Color(_alphas[i], r, g, b));
|
|
||||||
graphics0.DrawLine(&pen, from, i, to, i);
|
|
||||||
graphics2.DrawLine(&pen, from, _size - (i - 2 * _shift) - 1, to, _size - (i - 2 * _shift) - 1);
|
|
||||||
}
|
|
||||||
for (int i = _size; i < _size + 2 * _shift; ++i) {
|
|
||||||
Gdiplus::Pen pen(Gdiplus::Color(_alphas[i], r, g, b));
|
|
||||||
graphics2.DrawLine(&pen, from, _size - (i - 2 * _shift) - 1, to, _size - (i - 2 * _shift) - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_w > w) {
|
|
||||||
graphics0.FillRectangle(&brush, w - _size - _fullsize - _shift, 0, _fullsize - (_size - _shift), _size);
|
|
||||||
graphics2.FillRectangle(&brush, w - _size - _fullsize - _shift, 0, _fullsize - (_size - _shift), _size);
|
|
||||||
}
|
|
||||||
horCorners(w, &graphics0, &graphics2);
|
|
||||||
POINT p0 = { x + _size, y }, p2 = { x + _size, y + h - _size }, f = { 0, 0 };
|
|
||||||
SIZE s = { w - 2 * _size, _size };
|
|
||||||
updateWindow(0, &p0, &s);
|
|
||||||
updateWindow(2, &p2, &s);
|
|
||||||
} else if (x != _x || y != _y) {
|
|
||||||
POINT p0 = { x + _size, y }, p2 = { x + _size, y + h - _size };
|
|
||||||
updateWindow(0, &p0);
|
|
||||||
updateWindow(2, &p2);
|
|
||||||
} else if (h != _h) {
|
|
||||||
POINT p2 = { x + _size, y + h - _size };
|
|
||||||
updateWindow(2, &p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h != _h) {
|
|
||||||
int from = (_h > 2 * _fullsize + 2 * _shift) ? (_h - _fullsize) : (_fullsize + 2 * _shift);
|
|
||||||
int to = h - _fullsize;
|
|
||||||
if (h > max_h) {
|
|
||||||
from = (_fullsize + 2 * _shift);
|
|
||||||
max_h *= 2;
|
|
||||||
for (int i = 1; i < 4; i += 2) {
|
|
||||||
DeleteObject(bitmaps[i]);
|
|
||||||
bitmaps[i] = CreateCompatibleBitmap(dcs[i], _size, max_h);
|
|
||||||
SelectObject(dcs[i], bitmaps[i]);
|
|
||||||
}
|
|
||||||
initCorners(_PsInitVer);
|
|
||||||
}
|
|
||||||
Gdiplus::Graphics graphics1(dcs[1]), graphics3(dcs[3]);
|
|
||||||
graphics1.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
graphics3.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
|
||||||
|
|
||||||
Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b));
|
|
||||||
if (to > from) {
|
|
||||||
graphics1.FillRectangle(&brush, _size - _shift, from, _shift, to - from);
|
|
||||||
graphics3.FillRectangle(&brush, 0, from, _shift, to - from);
|
|
||||||
for (int i = 2 * _shift; i < _size + _shift; ++i) {
|
|
||||||
Gdiplus::Pen pen(Gdiplus::Color(_alphas[i], r, g, b));
|
|
||||||
graphics1.DrawLine(&pen, _size + _shift - i - 1, from, _size + _shift - i - 1, to);
|
|
||||||
graphics3.DrawLine(&pen, i - _shift, from, i - _shift, to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_h > h) {
|
|
||||||
graphics1.FillRectangle(&brush, 0, h - _fullsize, _size, _fullsize);
|
|
||||||
graphics3.FillRectangle(&brush, 0, h - _fullsize, _size, _fullsize);
|
|
||||||
}
|
|
||||||
verCorners(h, &graphics1, &graphics3);
|
|
||||||
|
|
||||||
POINT p1 = { x + w - _size, y }, p3 = { x, y }, f = { 0, 0 };
|
|
||||||
SIZE s = { _size, h };
|
|
||||||
updateWindow(1, &p1, &s);
|
|
||||||
updateWindow(3, &p3, &s);
|
|
||||||
} else if (x != _x || y != _y) {
|
|
||||||
POINT p1 = { x + w - _size, y }, p3 = { x, y };
|
|
||||||
updateWindow(1, &p1);
|
|
||||||
updateWindow(3, &p3);
|
|
||||||
} else if (w != _w) {
|
|
||||||
POINT p1 = { x + w - _size, y };
|
|
||||||
updateWindow(1, &p1);
|
|
||||||
}
|
|
||||||
_x = x;
|
|
||||||
_y = y;
|
|
||||||
_w = w;
|
|
||||||
_h = h;
|
|
||||||
|
|
||||||
if (hidden && (changes & Change::Shown)) {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
SetWindowPos(hwnds[i], hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
|
|
||||||
}
|
|
||||||
hidden = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateWindow(int i, POINT *p, SIZE *s = 0) {
|
|
||||||
static POINT f = { 0, 0 };
|
|
||||||
if (s) {
|
|
||||||
UpdateLayeredWindow(hwnds[i], (s ? screenDC : 0), p, s, (s ? dcs[i] : 0), (s ? (&f) : 0), noKeyColor, &blend, ULW_ALPHA);
|
|
||||||
} else {
|
|
||||||
SetWindowPos(hwnds[i], 0, p->x, p->y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy() {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
if (dcs[i]) DeleteDC(dcs[i]);
|
|
||||||
if (bitmaps[i]) DeleteObject(bitmaps[i]);
|
|
||||||
if (hwnds[i]) DestroyWindow(hwnds[i]);
|
|
||||||
dcs[i] = 0;
|
|
||||||
bitmaps[i] = 0;
|
|
||||||
hwnds[i] = 0;
|
|
||||||
}
|
|
||||||
if (screenDC) ReleaseDC(0, screenDC);
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow *window() const {
|
|
||||||
return _window;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
int _x = 0, _y = 0, _w = 0, _h = 0;
|
|
||||||
int _metaSize = 0, _fullsize = 0, _size = 0, _shift = 0;
|
|
||||||
QVector<BYTE> _alphas, _colors;
|
|
||||||
|
|
||||||
MainWindow *_window = nullptr;
|
|
||||||
bool hidden = true;
|
|
||||||
|
|
||||||
HWND hwnds[4];
|
|
||||||
HDC dcs[4], screenDC;
|
|
||||||
HBITMAP bitmaps[4];
|
|
||||||
int max_w = 0, max_h = 0;
|
|
||||||
BLENDFUNCTION blend;
|
|
||||||
|
|
||||||
BYTE r = 0, g = 0, b = 0;
|
|
||||||
COLORREF noKeyColor;
|
|
||||||
|
|
||||||
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
||||||
|
|
||||||
};
|
|
||||||
_PsShadowWindows _psShadowWindows;
|
|
||||||
|
|
||||||
LRESULT CALLBACK _PsShadowWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
||||||
const auto window = _psShadowWindows.window();
|
|
||||||
if (!window || !window->shadowsWorking()) {
|
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; ++i) {
|
|
||||||
if (_psShadowWindows.hwnds[i] && hwnd == _psShadowWindows.hwnds[i]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == 4) return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
||||||
|
|
||||||
switch (msg) {
|
|
||||||
case WM_CLOSE:
|
|
||||||
window->close();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_NCHITTEST: {
|
|
||||||
int32 xPos = GET_X_LPARAM(lParam), yPos = GET_Y_LPARAM(lParam);
|
|
||||||
switch (i) {
|
|
||||||
case 0: return HTTOP;
|
|
||||||
case 1: return (yPos < _psShadowWindows._y + _psSize) ? HTTOPRIGHT : ((yPos >= _psShadowWindows._y + _psShadowWindows._h - _psSize) ? HTBOTTOMRIGHT : HTRIGHT);
|
|
||||||
case 2: return HTBOTTOM;
|
|
||||||
case 3: return (yPos < _psShadowWindows._y + _psSize) ? HTTOPLEFT : ((yPos >= _psShadowWindows._y + _psShadowWindows._h - _psSize) ? HTBOTTOMLEFT : HTLEFT);
|
|
||||||
}
|
|
||||||
return HTTRANSPARENT;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case WM_NCACTIVATE: return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
||||||
case WM_NCLBUTTONDOWN:
|
|
||||||
case WM_NCLBUTTONUP:
|
|
||||||
case WM_NCLBUTTONDBLCLK:
|
|
||||||
case WM_NCMBUTTONDOWN:
|
|
||||||
case WM_NCMBUTTONUP:
|
|
||||||
case WM_NCMBUTTONDBLCLK:
|
|
||||||
case WM_NCRBUTTONDOWN:
|
|
||||||
case WM_NCRBUTTONUP:
|
|
||||||
case WM_NCRBUTTONDBLCLK:
|
|
||||||
case WM_NCXBUTTONDOWN:
|
|
||||||
case WM_NCXBUTTONUP:
|
|
||||||
case WM_NCXBUTTONDBLCLK:
|
|
||||||
case WM_NCMOUSEHOVER:
|
|
||||||
case WM_NCMOUSELEAVE:
|
|
||||||
case WM_NCMOUSEMOVE:
|
|
||||||
case WM_NCPOINTERUPDATE:
|
|
||||||
case WM_NCPOINTERDOWN:
|
|
||||||
case WM_NCPOINTERUP:
|
|
||||||
if (window && window->psHwnd()) {
|
|
||||||
if (msg == WM_NCLBUTTONDOWN) {
|
|
||||||
::SetForegroundWindow(window->psHwnd());
|
|
||||||
}
|
|
||||||
LRESULT res = SendMessage(window->psHwnd(), msg, wParam, lParam);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
case WM_ACTIVATE:
|
|
||||||
if (window && window->psHwnd() && wParam == WA_ACTIVE) {
|
|
||||||
if ((HWND)lParam != window->psHwnd()) {
|
|
||||||
::SetForegroundWindow(hwnd);
|
|
||||||
::SetWindowPos(window->psHwnd(), hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComPtr<ITaskbarList3> taskbarList;
|
ComPtr<ITaskbarList3> taskbarList;
|
||||||
|
|
||||||
bool handleSessionNotification = false;
|
bool handleSessionNotification = false;
|
||||||
|
|
@ -638,13 +107,17 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
|
||||||
if (!_taskbarCreatedMsgId) {
|
if (!_taskbarCreatedMsgId) {
|
||||||
_taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated");
|
_taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated");
|
||||||
}
|
}
|
||||||
if (!UseNativeDecorations()) {
|
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
|
||||||
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
|
if (_shadow && update.paletteChanged()) {
|
||||||
if (update.paletteChanged()) {
|
_shadow->setColor(st::windowShadowFg->c);
|
||||||
_psShadowWindows.setColor(st::windowShadowFg->c);
|
}
|
||||||
}
|
});
|
||||||
});
|
Core::App().settings().nativeWindowFrameChanges(
|
||||||
}
|
) | rpl::start_with_next([=] {
|
||||||
|
initShadows();
|
||||||
|
validateWindowTheme();
|
||||||
|
fixMaximizedWindow();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::TaskbarCreated() {
|
void MainWindow::TaskbarCreated() {
|
||||||
|
|
@ -654,23 +127,21 @@ void MainWindow::TaskbarCreated() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::shadowsUpdate(ShadowsChanges changes, WINDOWPOS *position) {
|
void MainWindow::shadowsUpdate(
|
||||||
if (!UseNativeDecorations()) {
|
Ui::Platform::WindowShadow::Changes changes,
|
||||||
_psShadowWindows.update(changes, position);
|
WINDOWPOS *position) {
|
||||||
|
if (_shadow) {
|
||||||
|
_shadow->update(changes, position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::shadowsActivate() {
|
void MainWindow::shadowsActivate() {
|
||||||
if (!UseNativeDecorations()) {
|
// _shadow->setColor(_shActive);
|
||||||
// _psShadowWindows.setColor(_shActive);
|
shadowsUpdate(Ui::Platform::WindowShadow::Change::Activate);
|
||||||
shadowsUpdate(ShadowsChange::Activate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::shadowsDeactivate() {
|
void MainWindow::shadowsDeactivate() {
|
||||||
// if (!UseNativeDecorations()) {
|
// _shadow->setColor(_shInactive);
|
||||||
// _psShadowWindows.setColor(_shInactive);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psShowTrayMenu() {
|
void MainWindow::psShowTrayMenu() {
|
||||||
|
|
@ -768,6 +239,10 @@ void MainWindow::workmodeUpdated(DBIWorkMode mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateWindowIcon() {
|
||||||
|
updateIconCounters();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::unreadCounterChangedHook() {
|
void MainWindow::unreadCounterChangedHook() {
|
||||||
setWindowTitle(titleText());
|
setWindowTitle(titleText());
|
||||||
updateIconCounters();
|
updateIconCounters();
|
||||||
|
|
@ -840,17 +315,22 @@ void MainWindow::initHook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initShadows() {
|
void MainWindow::initShadows() {
|
||||||
if (!UseNativeDecorations()) {
|
if (Core::App().settings().nativeWindowFrame()) {
|
||||||
_psShadowWindows.init(this, st::windowShadowFg->c);
|
_shadow.reset();
|
||||||
_shadowsWorking = true;
|
} else {
|
||||||
psUpdateMargins();
|
_shadow.emplace(this, st::windowShadowFg->c);
|
||||||
shadowsUpdate(ShadowsChange::Hidden);
|
|
||||||
}
|
}
|
||||||
|
updateCustomMargins();
|
||||||
|
firstShadowsUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::firstShadowsUpdate() {
|
void MainWindow::firstShadowsUpdate() {
|
||||||
if (!UseNativeDecorations() && !(windowState() & Qt::WindowMinimized) && !isHidden()) {
|
using Change = Ui::Platform::WindowShadow::Change;
|
||||||
shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized | ShadowsChange::Shown);
|
if ((windowState() & (Qt::WindowMinimized | Qt::WindowMaximized))
|
||||||
|
|| isHidden()) {
|
||||||
|
shadowsUpdate(Change::Hidden);
|
||||||
|
} else {
|
||||||
|
shadowsUpdate(Change::Moved | Change::Resized | Change::Shown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -907,19 +387,40 @@ void MainWindow::updateSystemMenu(Qt::WindowState state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psUpdateMargins() {
|
void MainWindow::updateCustomMargins() {
|
||||||
if (!ps_hWnd || _inUpdateMargins) return;
|
if (!ps_hWnd || _inUpdateMargins) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_inUpdateMargins = true;
|
_inUpdateMargins = true;
|
||||||
|
|
||||||
RECT r, a;
|
const auto margins = computeCustomMargins();
|
||||||
|
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
||||||
|
native->setWindowProperty(
|
||||||
|
windowHandle()->handle(),
|
||||||
|
qsl("WindowsCustomMargins"),
|
||||||
|
QVariant::fromValue<QMargins>(margins));
|
||||||
|
}
|
||||||
|
if (!_themeInited) {
|
||||||
|
_themeInited = true;
|
||||||
|
validateWindowTheme();
|
||||||
|
}
|
||||||
|
_inUpdateMargins = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMargins MainWindow::computeCustomMargins() {
|
||||||
|
if (Core::App().settings().nativeWindowFrame()) {
|
||||||
|
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
|
||||||
|
return QMargins();
|
||||||
|
}
|
||||||
|
auto r = RECT();
|
||||||
GetClientRect(ps_hWnd, &r);
|
GetClientRect(ps_hWnd, &r);
|
||||||
a = r;
|
|
||||||
|
|
||||||
LONG style = GetWindowLongPtr(ps_hWnd, GWL_STYLE), styleEx = GetWindowLongPtr(ps_hWnd, GWL_EXSTYLE);
|
auto a = r;
|
||||||
|
const auto style = GetWindowLongPtr(ps_hWnd, GWL_STYLE);
|
||||||
|
const auto styleEx = GetWindowLongPtr(ps_hWnd, GWL_EXSTYLE);
|
||||||
AdjustWindowRectEx(&a, style, false, styleEx);
|
AdjustWindowRectEx(&a, style, false, styleEx);
|
||||||
QMargins margins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom);
|
auto margins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom);
|
||||||
if (style & WS_MAXIMIZE) {
|
if (style & WS_MAXIMIZE) {
|
||||||
RECT w, m;
|
RECT w, m;
|
||||||
GetWindowRect(ps_hWnd, &w);
|
GetWindowRect(ps_hWnd, &w);
|
||||||
|
|
@ -948,23 +449,39 @@ void MainWindow::psUpdateMargins() {
|
||||||
SetWindowPos(ps_hWnd, 0, 0, 0, w.right - w.left - _deltaLeft - _deltaRight, w.bottom - w.top - _deltaBottom - _deltaTop, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION);
|
SetWindowPos(ps_hWnd, 0, 0, 0, w.right - w.left - _deltaLeft - _deltaRight, w.bottom - w.top - _deltaBottom - _deltaTop, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION);
|
||||||
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
|
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
|
||||||
}
|
}
|
||||||
|
return margins;
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
void MainWindow::validateWindowTheme() {
|
||||||
native->setWindowProperty(
|
if (IsWindows8OrGreater()) {
|
||||||
windowHandle()->handle(),
|
return;
|
||||||
qsl("WindowsCustomMargins"),
|
} else if (Dlls::SetWindowTheme != nullptr) {
|
||||||
QVariant::fromValue<QMargins>(margins));
|
if (Core::App().settings().nativeWindowFrame()) {
|
||||||
|
Dlls::SetWindowTheme(ps_hWnd, nullptr, nullptr);
|
||||||
|
} else {
|
||||||
|
Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
|
||||||
|
}
|
||||||
|
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
|
||||||
}
|
}
|
||||||
if (!_themeInited) {
|
}
|
||||||
_themeInited = true;
|
|
||||||
if (!IsWindows8OrGreater()) {
|
void MainWindow::fixMaximizedWindow() {
|
||||||
if (Dlls::SetWindowTheme != nullptr) {
|
auto r = RECT();
|
||||||
Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
|
GetClientRect(ps_hWnd, &r);
|
||||||
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
|
const auto style = GetWindowLongPtr(ps_hWnd, GWL_STYLE);
|
||||||
}
|
const auto styleEx = GetWindowLongPtr(ps_hWnd, GWL_EXSTYLE);
|
||||||
|
AdjustWindowRectEx(&r, style, false, styleEx);
|
||||||
|
if (style & WS_MAXIMIZE) {
|
||||||
|
auto w = RECT();
|
||||||
|
GetWindowRect(ps_hWnd, &w);
|
||||||
|
if (const auto hMonitor = MonitorFromRect(&w, MONITOR_DEFAULTTONEAREST)) {
|
||||||
|
MONITORINFO mi;
|
||||||
|
mi.cbSize = sizeof(mi);
|
||||||
|
GetMonitorInfo(hMonitor, &mi);
|
||||||
|
const auto m = mi.rcWork;
|
||||||
|
SetWindowPos(ps_hWnd, 0, 0, 0, m.right - m.left - _deltaLeft - _deltaRight, m.bottom - m.top - _deltaTop - _deltaBottom, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_inUpdateMargins = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND MainWindow::psHwnd() const {
|
HWND MainWindow::psHwnd() const {
|
||||||
|
|
@ -1000,10 +517,6 @@ MainWindow::~MainWindow() {
|
||||||
|
|
||||||
if (ps_menu) DestroyMenu(ps_menu);
|
if (ps_menu) DestroyMenu(ps_menu);
|
||||||
psDestroyIcons();
|
psDestroyIcons();
|
||||||
if (!UseNativeDecorations()) {
|
|
||||||
_shadowsWorking = false;
|
|
||||||
_psShadowWindows.destroy();
|
|
||||||
}
|
|
||||||
if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd);
|
if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd);
|
||||||
|
|
||||||
EventFilter::Destroy();
|
EventFilter::Destroy();
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "platform/platform_main_window.h"
|
#include "platform/platform_main_window.h"
|
||||||
|
#include "ui/platform/win/ui_window_shadow_win.h"
|
||||||
#include "base/platform/win/base_windows_h.h"
|
#include "base/platform/win/base_windows_h.h"
|
||||||
#include "base/flags.h"
|
#include "base/flags.h"
|
||||||
|
|
||||||
|
|
@ -30,7 +31,9 @@ public:
|
||||||
|
|
||||||
void psInitSysMenu();
|
void psInitSysMenu();
|
||||||
void updateSystemMenu(Qt::WindowState state);
|
void updateSystemMenu(Qt::WindowState state);
|
||||||
void psUpdateMargins();
|
void updateCustomMargins();
|
||||||
|
|
||||||
|
void updateWindowIcon() override;
|
||||||
|
|
||||||
void psRefreshTaskbarIcon();
|
void psRefreshTaskbarIcon();
|
||||||
|
|
||||||
|
|
@ -42,22 +45,11 @@ public:
|
||||||
static void TaskbarCreated();
|
static void TaskbarCreated();
|
||||||
|
|
||||||
// Custom shadows.
|
// Custom shadows.
|
||||||
enum class ShadowsChange {
|
|
||||||
Moved = (1 << 0),
|
|
||||||
Resized = (1 << 1),
|
|
||||||
Shown = (1 << 2),
|
|
||||||
Hidden = (1 << 3),
|
|
||||||
Activate = (1 << 4),
|
|
||||||
};
|
|
||||||
using ShadowsChanges = base::flags<ShadowsChange>;
|
|
||||||
friend inline constexpr auto is_flag_type(ShadowsChange) { return true; };
|
|
||||||
|
|
||||||
bool shadowsWorking() const {
|
|
||||||
return _shadowsWorking;
|
|
||||||
}
|
|
||||||
void shadowsActivate();
|
void shadowsActivate();
|
||||||
void shadowsDeactivate();
|
void shadowsDeactivate();
|
||||||
void shadowsUpdate(ShadowsChanges changes, WINDOWPOS *position = nullptr);
|
void shadowsUpdate(
|
||||||
|
Ui::Platform::WindowShadow::Changes changes,
|
||||||
|
WINDOWPOS *position = nullptr);
|
||||||
|
|
||||||
int deltaLeft() const {
|
int deltaLeft() const {
|
||||||
return _deltaLeft;
|
return _deltaLeft;
|
||||||
|
|
@ -99,12 +91,15 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateIconCounters();
|
void updateIconCounters();
|
||||||
|
QMargins computeCustomMargins();
|
||||||
|
void validateWindowTheme();
|
||||||
void psDestroyIcons();
|
void psDestroyIcons();
|
||||||
|
void fixMaximizedWindow();
|
||||||
|
|
||||||
static UINT _taskbarCreatedMsgId;
|
static UINT _taskbarCreatedMsgId;
|
||||||
|
|
||||||
bool _shadowsWorking = false;
|
std::optional<Ui::Platform::WindowShadow> _shadow;
|
||||||
|
|
||||||
bool _themeInited = false;
|
bool _themeInited = false;
|
||||||
bool _inUpdateMargins = false;
|
bool _inUpdateMargins = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,18 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
||||||
return object_ptr<TitleWidget>(parent);
|
return object_ptr<TitleWidget>(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline int PreviewTitleHeight() {
|
inline int PreviewTitleHeight() {
|
||||||
return Window::Theme::DefaultPreviewTitleHeight();
|
return Window::Theme::DefaultPreviewTitleHeight();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,56 +78,13 @@ bool EventFilter::nativeEventFilter(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventFilter::mainWindowEvent(
|
bool EventFilter::customWindowFrameEvent(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
UINT msg,
|
UINT msg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam,
|
LPARAM lParam,
|
||||||
LRESULT *result) {
|
LRESULT *result) {
|
||||||
using ShadowsChange = MainWindow::ShadowsChange;
|
|
||||||
|
|
||||||
if (const auto tbCreatedMsgId = Platform::MainWindow::TaskbarCreatedMsgId()) {
|
|
||||||
if (msg == tbCreatedMsgId) {
|
|
||||||
Platform::MainWindow::TaskbarCreated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UseNativeDecorations()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
|
|
||||||
case WM_TIMECHANGE: {
|
|
||||||
Core::App().checkAutoLockIn(100);
|
|
||||||
} 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) {
|
|
||||||
Ui::MarkInactivePress(_window, true);
|
|
||||||
}
|
|
||||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
|
||||||
_window->shadowsActivate();
|
|
||||||
} else {
|
|
||||||
_window->shadowsDeactivate();
|
|
||||||
}
|
|
||||||
if (Global::started()) {
|
|
||||||
_window->update();
|
|
||||||
}
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_NCPAINT: {
|
case WM_NCPAINT: {
|
||||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
|
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
|
||||||
if (result) *result = 0;
|
if (result) *result = 0;
|
||||||
|
|
@ -162,47 +119,6 @@ bool EventFilter::mainWindowEvent(
|
||||||
}
|
}
|
||||||
} return true;
|
} 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)) {
|
|
||||||
_window->shadowsUpdate(ShadowsChange::Hidden);
|
|
||||||
} else {
|
|
||||||
_window->shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized, (WINDOWPOS*)lParam);
|
|
||||||
}
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_SIZE: {
|
|
||||||
if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) {
|
|
||||||
if (wParam != SIZE_RESTORED || _window->windowState() != Qt::WindowNoState) {
|
|
||||||
Qt::WindowState state = Qt::WindowNoState;
|
|
||||||
if (wParam == SIZE_MAXIMIZED) {
|
|
||||||
state = Qt::WindowMaximized;
|
|
||||||
} else if (wParam == SIZE_MINIMIZED) {
|
|
||||||
state = Qt::WindowMinimized;
|
|
||||||
}
|
|
||||||
emit _window->windowHandle()->windowStateChanged(state);
|
|
||||||
} else {
|
|
||||||
_window->positionUpdated();
|
|
||||||
}
|
|
||||||
_window->psUpdateMargins();
|
|
||||||
MainWindow::ShadowsChanges changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? ShadowsChange::Hidden : (ShadowsChange::Resized | ShadowsChange::Shown);
|
|
||||||
_window->shadowsUpdate(changes);
|
|
||||||
}
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_SHOWWINDOW: {
|
|
||||||
LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
|
|
||||||
auto changes = ShadowsChange::Resized | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) ? ShadowsChange::Shown : ShadowsChange::Hidden);
|
|
||||||
_window->shadowsUpdate(changes);
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_MOVE: {
|
|
||||||
_window->shadowsUpdate(ShadowsChange::Moved);
|
|
||||||
_window->positionUpdated();
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_NCHITTEST: {
|
case WM_NCHITTEST: {
|
||||||
if (!result) return false;
|
if (!result) return false;
|
||||||
|
|
||||||
|
|
@ -230,6 +146,103 @@ bool EventFilter::mainWindowEvent(
|
||||||
case WM_NCRBUTTONUP: {
|
case WM_NCRBUTTONUP: {
|
||||||
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
||||||
} return true;
|
} return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventFilter::mainWindowEvent(
|
||||||
|
HWND hWnd,
|
||||||
|
UINT msg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam,
|
||||||
|
LRESULT *result) {
|
||||||
|
using Change = Ui::Platform::WindowShadow::Change;
|
||||||
|
|
||||||
|
if (const auto tbCreatedMsgId = Platform::MainWindow::TaskbarCreatedMsgId()) {
|
||||||
|
if (msg == tbCreatedMsgId) {
|
||||||
|
Platform::MainWindow::TaskbarCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Core::App().settings().nativeWindowFrame()) {
|
||||||
|
if (customWindowFrameEvent(hWnd, msg, wParam, lParam, result)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
|
||||||
|
case WM_TIMECHANGE: {
|
||||||
|
Core::App().checkAutoLockIn(100);
|
||||||
|
} 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) {
|
||||||
|
Ui::MarkInactivePress(_window, true);
|
||||||
|
}
|
||||||
|
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||||
|
_window->shadowsActivate();
|
||||||
|
} else {
|
||||||
|
_window->shadowsDeactivate();
|
||||||
|
}
|
||||||
|
if (Global::started()) {
|
||||||
|
_window->update();
|
||||||
|
}
|
||||||
|
} return false;
|
||||||
|
|
||||||
|
case WM_WINDOWPOSCHANGING:
|
||||||
|
case WM_WINDOWPOSCHANGED: {
|
||||||
|
WINDOWPLACEMENT wp;
|
||||||
|
wp.length = sizeof(WINDOWPLACEMENT);
|
||||||
|
if (GetWindowPlacement(hWnd, &wp) && (wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED)) {
|
||||||
|
_window->shadowsUpdate(Change::Hidden);
|
||||||
|
} else {
|
||||||
|
_window->shadowsUpdate(Change::Moved | Change::Resized, (WINDOWPOS*)lParam);
|
||||||
|
}
|
||||||
|
} return false;
|
||||||
|
|
||||||
|
case WM_SIZE: {
|
||||||
|
if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) {
|
||||||
|
if (wParam != SIZE_RESTORED || _window->windowState() != Qt::WindowNoState) {
|
||||||
|
Qt::WindowState state = Qt::WindowNoState;
|
||||||
|
if (wParam == SIZE_MAXIMIZED) {
|
||||||
|
state = Qt::WindowMaximized;
|
||||||
|
} else if (wParam == SIZE_MINIMIZED) {
|
||||||
|
state = Qt::WindowMinimized;
|
||||||
|
}
|
||||||
|
emit _window->windowHandle()->windowStateChanged(state);
|
||||||
|
} else {
|
||||||
|
_window->positionUpdated();
|
||||||
|
}
|
||||||
|
_window->updateCustomMargins();
|
||||||
|
const auto changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? Change::Hidden : (Change::Resized | Change::Shown);
|
||||||
|
_window->shadowsUpdate(changes);
|
||||||
|
}
|
||||||
|
} return false;
|
||||||
|
|
||||||
|
case WM_SHOWWINDOW: {
|
||||||
|
LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
|
||||||
|
const auto changes = Change::Resized | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) ? Change::Shown : Change::Hidden);
|
||||||
|
_window->shadowsUpdate(changes);
|
||||||
|
} return false;
|
||||||
|
|
||||||
|
case WM_MOVE: {
|
||||||
|
_window->shadowsUpdate(Change::Moved);
|
||||||
|
_window->positionUpdated();
|
||||||
|
} return false;
|
||||||
|
|
||||||
case WM_SYSCOMMAND: {
|
case WM_SYSCOMMAND: {
|
||||||
if (wParam == SC_MOUSEMENU) {
|
if (wParam == SC_MOUSEMENU) {
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,13 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit EventFilter(not_null<MainWindow*> window);
|
explicit EventFilter(not_null<MainWindow*> window);
|
||||||
|
|
||||||
|
bool customWindowFrameEvent(
|
||||||
|
HWND hWnd,
|
||||||
|
UINT msg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam,
|
||||||
|
LRESULT *result);
|
||||||
|
|
||||||
not_null<MainWindow*> _window;
|
not_null<MainWindow*> _window;
|
||||||
bool _sessionLoggedOff = false;
|
bool _sessionLoggedOff = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/about_box.h"
|
#include "boxes/about_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
|
#include "platform/platform_window_title.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
|
@ -407,6 +408,20 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
||||||
}, taskbar->lifetime());
|
}, taskbar->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Platform::AllowNativeWindowFrameToggle()) {
|
||||||
|
const auto nativeFrame = addCheckbox(
|
||||||
|
"Use system window frame",
|
||||||
|
Core::App().settings().nativeWindowFrame());
|
||||||
|
|
||||||
|
nativeFrame->checkedChanges(
|
||||||
|
) | rpl::filter([](bool checked) {
|
||||||
|
return (checked != Core::App().settings().nativeWindowFrame());
|
||||||
|
}) | rpl::start_with_next([=](bool checked) {
|
||||||
|
Core::App().settings().setNativeWindowFrame(checked);
|
||||||
|
Core::App().saveSettingsDelayed();
|
||||||
|
}, nativeFrame->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
if (Platform::AutostartSupported()) {
|
if (Platform::AutostartSupported()) {
|
||||||
const auto minimizedToggled = [] {
|
const auto minimizedToggled = [] {
|
||||||
return cStartMinimized() && !Global::LocalPasscode();
|
return cStartMinimized() && !Global::LocalPasscode();
|
||||||
|
|
|
||||||
|
|
@ -776,7 +776,7 @@ void FileLoadTask::process() {
|
||||||
}
|
}
|
||||||
_result->filesize = (int32)qMin(filesize, qint64(INT_MAX));
|
_result->filesize = (int32)qMin(filesize, qint64(INT_MAX));
|
||||||
|
|
||||||
if (!filesize || filesize > App::kFileSizeLimit) {
|
if (!filesize || filesize > kFileSizeLimit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -963,7 +963,7 @@ void FileLoadTask::finish() {
|
||||||
tr::lng_send_image_empty(tr::now, lt_name, _filepath)),
|
tr::lng_send_image_empty(tr::now, lt_name, _filepath)),
|
||||||
Ui::LayerOption::KeepOther);
|
Ui::LayerOption::KeepOther);
|
||||||
removeFromAlbum();
|
removeFromAlbum();
|
||||||
} else if (_result->filesize > App::kFileSizeLimit) {
|
} else if (_result->filesize > kFileSizeLimit) {
|
||||||
Ui::show(
|
Ui::show(
|
||||||
Box<InformBox>(
|
Box<InformBox>(
|
||||||
tr::lng_send_image_too_large(tr::now, lt_name, _filepath)),
|
tr::lng_send_image_too_large(tr::now, lt_name, _filepath)),
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/variant.h"
|
#include "base/variant.h"
|
||||||
#include "api/api_common.h"
|
#include "api/api_common.h"
|
||||||
|
|
||||||
|
constexpr auto kFileSizeLimit = 2000 * 1024 * 1024; // Load files up to 1500mb
|
||||||
|
|
||||||
enum class CompressConfirm {
|
enum class CompressConfirm {
|
||||||
Auto,
|
Auto,
|
||||||
Yes,
|
Yes,
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ MimeDataState ComputeMimeDataState(const QMimeData *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto filesize = info.size();
|
const auto filesize = info.size();
|
||||||
if (filesize > App::kFileSizeLimit) {
|
if (filesize > kFileSizeLimit) {
|
||||||
return MimeDataState::None;
|
return MimeDataState::None;
|
||||||
} else if (allAreSmallImages) {
|
} else if (allAreSmallImages) {
|
||||||
if (filesize > App::kImageSizeLimit) {
|
if (filesize > App::kImageSizeLimit) {
|
||||||
|
|
@ -237,7 +237,7 @@ PreparedList PrepareMediaList(const QStringList &files, int previewWidth) {
|
||||||
PreparedList::Error::EmptyFile,
|
PreparedList::Error::EmptyFile,
|
||||||
file
|
file
|
||||||
};
|
};
|
||||||
} else if (filesize > App::kFileSizeLimit) {
|
} else if (filesize > kFileSizeLimit) {
|
||||||
return {
|
return {
|
||||||
PreparedList::Error::TooLargeFile,
|
PreparedList::Error::TooLargeFile,
|
||||||
file
|
file
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/crc32hash.h"
|
#include "base/crc32hash.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
@ -265,9 +266,14 @@ void MainWindow::init() {
|
||||||
|
|
||||||
updatePalette();
|
updatePalette();
|
||||||
|
|
||||||
if (!UseNativeDecorations() && (_title = Platform::CreateTitleWidget(this))) {
|
if (Platform::AllowNativeWindowFrameToggle()) {
|
||||||
_title->init();
|
Core::App().settings().nativeWindowFrameChanges(
|
||||||
|
) | rpl::start_with_next([=](bool native) {
|
||||||
|
refreshTitleWidget();
|
||||||
|
recountGeometryConstraints();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
refreshTitleWidget();
|
||||||
|
|
||||||
initSize();
|
initSize();
|
||||||
updateUnreadCounter();
|
updateUnreadCounter();
|
||||||
|
|
@ -340,9 +346,34 @@ int MainWindow::computeMinHeight() const {
|
||||||
return title + outdated + st::windowMinHeight;
|
return title + outdated + st::windowMinHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initSize() {
|
void MainWindow::refreshTitleWidget() {
|
||||||
|
if (Platform::AllowNativeWindowFrameToggle()
|
||||||
|
&& Core::App().settings().nativeWindowFrame()) {
|
||||||
|
_title.destroy();
|
||||||
|
if (Platform::NativeTitleRequiresShadow()) {
|
||||||
|
_titleShadow.create(this);
|
||||||
|
_titleShadow->show();
|
||||||
|
}
|
||||||
|
} else if ((_title = Platform::CreateTitleWidget(this))) {
|
||||||
|
_title->show();
|
||||||
|
_title->init();
|
||||||
|
_titleShadow.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateMinimumSize() {
|
||||||
setMinimumWidth(computeMinWidth());
|
setMinimumWidth(computeMinWidth());
|
||||||
setMinimumHeight(computeMinHeight());
|
setMinimumHeight(computeMinHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::recountGeometryConstraints() {
|
||||||
|
updateMinimumSize();
|
||||||
|
updateControlsGeometry();
|
||||||
|
fixOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::initSize() {
|
||||||
|
updateMinimumSize();
|
||||||
|
|
||||||
auto position = cWindowPos();
|
auto position = cWindowPos();
|
||||||
DEBUG_LOG(("Window Pos: Initializing first %1, %2, %3, %4 (maximized %5)").arg(position.x).arg(position.y).arg(position.w).arg(position.h).arg(Logs::b(position.maximized)));
|
DEBUG_LOG(("Window Pos: Initializing first %1, %2, %3, %4 (maximized %5)").arg(position.x).arg(position.y).arg(position.w).arg(position.h).arg(Logs::b(position.maximized)));
|
||||||
|
|
@ -455,6 +486,9 @@ void MainWindow::updateControlsGeometry() {
|
||||||
_title->setGeometry(0, bodyTop, width(), _title->height());
|
_title->setGeometry(0, bodyTop, width(), _title->height());
|
||||||
bodyTop += _title->height();
|
bodyTop += _title->height();
|
||||||
}
|
}
|
||||||
|
if (_titleShadow) {
|
||||||
|
_titleShadow->setGeometry(0, bodyTop, width(), st::lineWidth);
|
||||||
|
}
|
||||||
if (_outdated) {
|
if (_outdated) {
|
||||||
Ui::SendPendingMoveResizeEvents(_outdated.data());
|
Ui::SendPendingMoveResizeEvents(_outdated.data());
|
||||||
_outdated->resizeToWidth(width());
|
_outdated->resizeToWidth(width());
|
||||||
|
|
@ -637,6 +671,8 @@ void MainWindow::launchDrag(std::unique_ptr<QMimeData> data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() = default;
|
MainWindow::~MainWindow() {
|
||||||
|
_title.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ class Account;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class BoxContent;
|
class BoxContent;
|
||||||
|
class PlainShadow;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
@ -81,6 +82,8 @@ public:
|
||||||
|
|
||||||
virtual void updateTrayMenu(bool force = false) {
|
virtual void updateTrayMenu(bool force = false) {
|
||||||
}
|
}
|
||||||
|
virtual void fixOrder() {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
|
@ -102,6 +105,7 @@ public:
|
||||||
int computeMinWidth() const;
|
int computeMinWidth() const;
|
||||||
int computeMinHeight() const;
|
int computeMinHeight() const;
|
||||||
|
|
||||||
|
void recountGeometryConstraints();
|
||||||
virtual void updateControlsGeometry();
|
virtual void updateControlsGeometry();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
@ -174,6 +178,8 @@ protected:
|
||||||
void updateUnreadCounter();
|
void updateUnreadCounter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void refreshTitleWidget();
|
||||||
|
void updateMinimumSize();
|
||||||
void updatePalette();
|
void updatePalette();
|
||||||
void initSize();
|
void initSize();
|
||||||
|
|
||||||
|
|
@ -185,6 +191,7 @@ private:
|
||||||
bool _positionInited = false;
|
bool _positionInited = false;
|
||||||
|
|
||||||
object_ptr<TitleWidget> _title = { nullptr };
|
object_ptr<TitleWidget> _title = { nullptr };
|
||||||
|
object_ptr<Ui::PlainShadow> _titleShadow = { nullptr };
|
||||||
object_ptr<Ui::RpWidget> _outdated;
|
object_ptr<Ui::RpWidget> _outdated;
|
||||||
object_ptr<Ui::RpWidget> _body;
|
object_ptr<Ui::RpWidget> _body;
|
||||||
object_ptr<TWidget> _rightColumn = { nullptr };
|
object_ptr<TWidget> _rightColumn = { nullptr };
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_updates.h"
|
#include "api/api_updates.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "platform/platform_window_title.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
#include "main/main_domain.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
|
@ -241,6 +242,13 @@ void Controller::showSettings() {
|
||||||
_widget.showSettings();
|
_widget.showSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Controller::verticalShadowTop() const {
|
||||||
|
return (Platform::NativeTitleRequiresShadow()
|
||||||
|
&& Core::App().settings().nativeWindowFrame())
|
||||||
|
? st::lineWidth
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::showToast(const QString &text) {
|
void Controller::showToast(const QString &text) {
|
||||||
Ui::Toast::Show(_widget.bodyWidget(), text);
|
Ui::Toast::Show(_widget.bodyWidget(), text);
|
||||||
}
|
}
|
||||||
|
|
@ -257,9 +265,7 @@ void Controller::showRightColumn(object_ptr<TWidget> widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::sideBarChanged() {
|
void Controller::sideBarChanged() {
|
||||||
_widget.setMinimumWidth(_widget.computeMinWidth());
|
_widget.recountGeometryConstraints();
|
||||||
_widget.updateControlsGeometry();
|
|
||||||
_widget.fixOrder();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::activate() {
|
void Controller::activate() {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ public:
|
||||||
|
|
||||||
void showSettings();
|
void showSettings();
|
||||||
|
|
||||||
|
[[nodiscard]] int verticalShadowTop() const;
|
||||||
|
|
||||||
template <typename BoxType>
|
template <typename BoxType>
|
||||||
QPointer<BoxType> show(
|
QPointer<BoxType> show(
|
||||||
object_ptr<BoxType> content,
|
object_ptr<BoxType> content,
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
#include "base/call_delayed.h"
|
||||||
|
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// If we toggle frameless window hint in maximized window, and
|
||||||
|
// show it back too quickly, the mouse position inside the window
|
||||||
|
// won't be correct (from Qt-s point of view) until we Alt-Tab from
|
||||||
|
// that window. If we show the window back with this delay it works.
|
||||||
|
constexpr auto kShowAfterFramelessToggleDelay = crl::time(1000);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TitleWidgetQt::TitleWidgetQt(QWidget *parent)
|
TitleWidgetQt::TitleWidgetQt(QWidget *parent)
|
||||||
: TitleWidget(parent)
|
: TitleWidget(parent)
|
||||||
|
|
@ -45,11 +55,35 @@ TitleWidgetQt::TitleWidgetQt(QWidget *parent)
|
||||||
|
|
||||||
QCoreApplication::instance()->installEventFilter(this);
|
QCoreApplication::instance()->installEventFilter(this);
|
||||||
|
|
||||||
window()->setWindowFlag(Qt::FramelessWindowHint, true);
|
_windowWasFrameless = (window()->windowFlags() & Qt::FramelessWindowHint) != 0;
|
||||||
|
if (!_windowWasFrameless) {
|
||||||
|
toggleFramelessWindow(true);
|
||||||
|
}
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
resize(width(), _st.height);
|
resize(width(), _st.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TitleWidgetQt::~TitleWidgetQt() {
|
||||||
|
restoreCursor();
|
||||||
|
if (!_windowWasFrameless) {
|
||||||
|
toggleFramelessWindow(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleWidgetQt::toggleFramelessWindow(bool enabled) {
|
||||||
|
// setWindowFlag calls setParent(parentWidget(), newFlags), which
|
||||||
|
// always calls hide() explicitly, we have to show() the window back.
|
||||||
|
const auto top = window();
|
||||||
|
const auto hidden = top->isHidden();
|
||||||
|
top->setWindowFlag(Qt::FramelessWindowHint, enabled);
|
||||||
|
if (!hidden) {
|
||||||
|
base::call_delayed(
|
||||||
|
kShowAfterFramelessToggleDelay,
|
||||||
|
top,
|
||||||
|
[=] { top->show(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TitleWidgetQt::init() {
|
void TitleWidgetQt::init() {
|
||||||
connect(
|
connect(
|
||||||
window()->windowHandle(),
|
window()->windowHandle(),
|
||||||
|
|
@ -103,7 +137,7 @@ void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||||
bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|
bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|
||||||
if (e->type() == QEvent::MouseMove
|
if (e->type() == QEvent::MouseMove
|
||||||
|| e->type() == QEvent::MouseButtonPress) {
|
|| e->type() == QEvent::MouseButtonPress) {
|
||||||
if(window()->isAncestorOf(static_cast<QWidget*>(obj))) {
|
if (window()->isAncestorOf(static_cast<QWidget*>(obj))) {
|
||||||
const auto mouseEvent = static_cast<QMouseEvent*>(e);
|
const auto mouseEvent = static_cast<QMouseEvent*>(e);
|
||||||
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint());
|
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint());
|
||||||
|
|
||||||
|
|
@ -111,7 +145,7 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|
||||||
updateCursor(edges);
|
updateCursor(edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e->type() == QEvent::MouseButtonPress
|
if (e->type() == QEvent::MouseButtonPress
|
||||||
&& mouseEvent->button() == Qt::LeftButton
|
&& mouseEvent->button() == Qt::LeftButton
|
||||||
&& window()->windowState() != Qt::WindowMaximized) {
|
&& window()->windowState() != Qt::WindowMaximized) {
|
||||||
return startResize(edges);
|
return startResize(edges);
|
||||||
|
|
@ -119,9 +153,7 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|
||||||
}
|
}
|
||||||
} else if (e->type() == QEvent::Leave) {
|
} else if (e->type() == QEvent::Leave) {
|
||||||
if (window() == static_cast<QWidget*>(obj)) {
|
if (window() == static_cast<QWidget*>(obj)) {
|
||||||
while (QGuiApplication::overrideCursor()) {
|
restoreCursor();
|
||||||
QGuiApplication::restoreOverrideCursor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,14 +228,22 @@ Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TitleWidgetQt::restoreCursor() {
|
||||||
|
if (_cursorOverriden) {
|
||||||
|
_cursorOverriden = false;
|
||||||
|
QGuiApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TitleWidgetQt::updateCursor(Qt::Edges edges) {
|
void TitleWidgetQt::updateCursor(Qt::Edges edges) {
|
||||||
if (!edges || window()->windowState() == Qt::WindowMaximized) {
|
if (!edges || window()->windowState() == Qt::WindowMaximized) {
|
||||||
while (QGuiApplication::overrideCursor()) {
|
restoreCursor();
|
||||||
QGuiApplication::restoreOverrideCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (!QGuiApplication::overrideCursor()) {
|
} else if (!QGuiApplication::overrideCursor()) {
|
||||||
|
_cursorOverriden = false;
|
||||||
|
}
|
||||||
|
if (!_cursorOverriden) {
|
||||||
|
_cursorOverriden = true;
|
||||||
QGuiApplication::setOverrideCursor(QCursor());
|
QGuiApplication::setOverrideCursor(QCursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace Window {
|
||||||
class TitleWidgetQt : public TitleWidget {
|
class TitleWidgetQt : public TitleWidget {
|
||||||
public:
|
public:
|
||||||
TitleWidgetQt(QWidget *parent);
|
TitleWidgetQt(QWidget *parent);
|
||||||
|
~TitleWidgetQt();
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
|
|
||||||
|
|
@ -40,8 +41,10 @@ private:
|
||||||
void updateButtonsState();
|
void updateButtonsState();
|
||||||
void updateControlsPosition();
|
void updateControlsPosition();
|
||||||
|
|
||||||
|
void toggleFramelessWindow(bool enabled);
|
||||||
Qt::Edges edgesFromPos(const QPoint &pos);
|
Qt::Edges edgesFromPos(const QPoint &pos);
|
||||||
void updateCursor(Qt::Edges edges);
|
void updateCursor(Qt::Edges edges);
|
||||||
|
void restoreCursor();
|
||||||
bool startResize(Qt::Edges edges);
|
bool startResize(Qt::Edges edges);
|
||||||
|
|
||||||
const style::WindowTitle &_st;
|
const style::WindowTitle &_st;
|
||||||
|
|
@ -52,6 +55,8 @@ private:
|
||||||
|
|
||||||
bool _maximizedState = false;
|
bool _maximizedState = false;
|
||||||
bool _activeState = false;
|
bool _activeState = false;
|
||||||
|
bool _windowWasFrameless = false;
|
||||||
|
bool _cursorOverriden = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
AppVersion 2001017
|
AppVersion 2001018
|
||||||
AppVersionStrMajor 2.1
|
AppVersionStrMajor 2.1
|
||||||
AppVersionStrSmall 2.1.17
|
AppVersionStrSmall 2.1.18
|
||||||
AppVersionStr 2.1.17
|
AppVersionStr 2.1.18
|
||||||
BetaChannel 1
|
BetaChannel 1
|
||||||
AlphaVersion 0
|
AlphaVersion 0
|
||||||
AppVersionOriginal 2.1.17.beta
|
AppVersionOriginal 2.1.18.beta
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 11a39d9d941e4cd1c60a0c97352cbf89700f42fc
|
Subproject commit c262a0931e4b32ff156aa12cb2657c8cdd444c69
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
2.1.18 beta (08.07.20)
|
||||||
|
|
||||||
|
- Fix a possible crash in Picture-in-Picture video player.
|
||||||
|
- Fix copying links from message texts.
|
||||||
|
- Raise file size limit to 2000 MB.
|
||||||
|
- Allow using system window frame in Windows and Linux.
|
||||||
|
|
||||||
2.1.17 beta (02.07.20)
|
2.1.17 beta (02.07.20)
|
||||||
|
|
||||||
- Fix messages editing in a non-active account.
|
- Fix messages editing in a non-active account.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue