diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 61592e775..7de3eb572 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -338,6 +338,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_update_fail" = "Update check failed :(";
"lng_settings_workmode_tray" = "Show tray 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_start_min" = "Launch minimized";
"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_settings_system" = "System";
-"ktg_settings_use_native_decorations" = "Native window decorations";
"ktg_settings_other" = "Other";
"ktg_profile_copy_id" = "Copy ID";
diff --git a/Telegram/Resources/langs/rewrites/en.json b/Telegram/Resources/langs/rewrites/en.json
index fd4a941fe..6b7804b9e 100644
--- a/Telegram/Resources/langs/rewrites/en.json
+++ b/Telegram/Resources/langs/rewrites/en.json
@@ -67,7 +67,6 @@
"ktg_net_speed_boost_medium": "Medium",
"ktg_net_speed_boost_big": "Big",
"ktg_settings_system": "System",
- "ktg_settings_use_native_decorations": "Native window decorations",
"ktg_settings_other": "Other",
"ktg_profile_copy_id": "Copy ID",
"ktg_profile_bot_id": "Bot ID",
diff --git a/Telegram/Resources/langs/rewrites/pl.json b/Telegram/Resources/langs/rewrites/pl.json
index 719688518..8ce3b667e 100644
--- a/Telegram/Resources/langs/rewrites/pl.json
+++ b/Telegram/Resources/langs/rewrites/pl.json
@@ -67,7 +67,6 @@
"ktg_net_speed_boost_medium": "Średnie",
"ktg_net_speed_boost_big": "Duże",
"ktg_settings_system": "System",
- "ktg_settings_use_native_decorations": "Natywne dekoracje okna",
"ktg_settings_other": "Inne",
"ktg_profile_copy_id": "Kopiuj ID",
"ktg_profile_bot_id": "ID Bota",
diff --git a/Telegram/Resources/langs/rewrites/ru.json b/Telegram/Resources/langs/rewrites/ru.json
index e4eac04ac..219f3d172 100644
--- a/Telegram/Resources/langs/rewrites/ru.json
+++ b/Telegram/Resources/langs/rewrites/ru.json
@@ -66,7 +66,6 @@
"ktg_net_speed_boost_medium": "Среднее",
"ktg_net_speed_boost_big": "Высокое",
"ktg_settings_system": "Система",
- "ktg_settings_use_native_decorations": "Системная рамка окна",
"ktg_settings_other": "Прочие",
"ktg_profile_copy_id": "Копировать ID",
"ktg_profile_bot_id": "ID бота",
diff --git a/Telegram/Resources/langs/rewrites/tr.json b/Telegram/Resources/langs/rewrites/tr.json
index 39069fabd..b5bdd42c1 100644
--- a/Telegram/Resources/langs/rewrites/tr.json
+++ b/Telegram/Resources/langs/rewrites/tr.json
@@ -67,7 +67,6 @@
"ktg_net_speed_boost_medium": "orta",
"ktg_net_speed_boost_big": "Güçlü",
"ktg_settings_system": "sistem",
- "ktg_settings_use_native_decorations": "Yerel pencere süslemeleri",
"ktg_settings_other": "Başka",
"ktg_profile_copy_id": "ID kopyala",
"ktg_profile_bot_id": "Bot ID",
diff --git a/Telegram/Resources/langs/rewrites/uk.json b/Telegram/Resources/langs/rewrites/uk.json
index 64824f3ce..8c04cd56c 100644
--- a/Telegram/Resources/langs/rewrites/uk.json
+++ b/Telegram/Resources/langs/rewrites/uk.json
@@ -66,7 +66,6 @@
"ktg_net_speed_boost_medium": "Середнє",
"ktg_net_speed_boost_big": "Високе",
"ktg_settings_system": "Система",
- "ktg_settings_use_native_decorations": "Системна рамка вікна",
"ktg_settings_other": "Інші",
"ktg_profile_copy_id": "Копіювати ID",
"ktg_profile_bot_id": "ID бота",
diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index a20191a2b..bf7544073 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -9,7 +9,7 @@
+ Version="2.1.18.0" />
Telegram Desktop
Telegram FZ-LLC
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index 3863a0ba7..48e71950a 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,17,0
- PRODUCTVERSION 2,1,17,0
+ FILEVERSION 2,1,18,0
+ PRODUCTVERSION 2,1,18,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
- VALUE "FileVersion", "2.1.17.0"
+ VALUE "FileVersion", "2.1.18.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "2.1.17.0"
+ VALUE "ProductVersion", "2.1.18.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index 25630bcad..6c71d6a0b 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,17,0
- PRODUCTVERSION 2,1,17,0
+ FILEVERSION 2,1,18,0
+ PRODUCTVERSION 2,1,18,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
- VALUE "FileVersion", "2.1.17.0"
+ VALUE "FileVersion", "2.1.18.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "2.1.17.0"
+ VALUE "ProductVersion", "2.1.18.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h
index 6d1543889..fc7c3c6a8 100644
--- a/Telegram/SourceFiles/app.h
+++ b/Telegram/SourceFiles/app.h
@@ -85,7 +85,6 @@ namespace App {
void setLaunchState(LaunchState state);
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
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);
diff --git a/Telegram/SourceFiles/core/changelogs.cpp b/Telegram/SourceFiles/core/changelogs.cpp
index aa328f84e..ee6e25e8b 100644
--- a/Telegram/SourceFiles/core/changelogs.cpp
+++ b/Telegram/SourceFiles/core/changelogs.cpp
@@ -61,7 +61,17 @@ std::map BetaLogs() {
"- Fix high definition GIF animations opening in media viewer.\n"
"- 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."
+ },
};
};
diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp
index 23c5d0eaf..1988fec58 100644
--- a/Telegram/SourceFiles/core/core_settings.cpp
+++ b/Telegram/SourceFiles/core/core_settings.cpp
@@ -105,7 +105,8 @@ QByteArray Settings::serialize() const {
1000000))
<< qint32(_thirdColumnWidth.current())
<< qint32(_thirdSectionExtendedBy)
- << qint32(_notifyFromAll ? 1 : 0);
+ << qint32(_notifyFromAll ? 1 : 0)
+ << qint32(_nativeWindowFrame.current() ? 1 : 0);
}
return result;
}
@@ -169,6 +170,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
qint32 thirdColumnWidth = _thirdColumnWidth.current();
qint32 thirdSectionExtendedBy = _thirdSectionExtendedBy;
qint32 notifyFromAll = _notifyFromAll ? 1 : 0;
+ qint32 nativeWindowFrame = _nativeWindowFrame.current() ? 1 : 0;
stream >> themesAccentColors;
if (!stream.atEnd()) {
@@ -243,6 +245,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
>> notifyFromAll;
dialogsWidthRatio = snap(dialogsWidthRatioInt / 1000000., 0., 1.);
}
+ if (!stream.atEnd()) {
+ stream >> nativeWindowFrame;
+ }
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()"));
@@ -335,6 +340,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
_tabbedSelectorSectionEnabled = false;
}
_notifyFromAll = (notifyFromAll == 1);
+ _nativeWindowFrame = (nativeWindowFrame == 1);
}
bool Settings::chatWide() const {
diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h
index b8eae179e..144b4977c 100644
--- a/Telegram/SourceFiles/core/core_settings.h
+++ b/Telegram/SourceFiles/core/core_settings.h
@@ -407,6 +407,15 @@ public:
[[nodiscard]] bool notifyFromAll() const {
return _notifyFromAll;
}
+ void setNativeWindowFrame(bool value) {
+ _nativeWindowFrame = value;
+ }
+ [[nodiscard]] bool nativeWindowFrame() const {
+ return _nativeWindowFrame.current();
+ }
+ [[nodiscard]] rpl::producer nativeWindowFrameChanges() const {
+ return _nativeWindowFrame.changes();
+ }
[[nodiscard]] static bool ThirdColumnByDefault();
[[nodiscard]] float64 DefaultDialogsWidthRatio();
@@ -474,6 +483,7 @@ private:
rpl::variable _dialogsWidthRatio; // per-window
rpl::variable _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
bool _notifyFromAll = true;
+ rpl::variable _nativeWindowFrame = false;
bool _tabbedReplacedWithInfo = false; // per-window
rpl::event_stream _tabbedReplacedWithInfoValue; // per-window
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 2b1ab8843..a6c4a60c8 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Kotatogram Desktop"_cs;
constexpr auto AppFile = "Kotatogram"_cs;
-constexpr auto AppVersion = 2001017;
-constexpr auto AppVersionStr = "2.1.17";
+constexpr auto AppVersion = 2001018;
+constexpr auto AppVersionStr = "2.1.18";
constexpr auto AppBetaVersion = true;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
diff --git a/Telegram/SourceFiles/data/data_auto_download.h b/Telegram/SourceFiles/data/data_auto_download.h
index ab2a6fe4e..37c21a620 100644
--- a/Telegram/SourceFiles/data/data_auto_download.h
+++ b/Telegram/SourceFiles/data/data_auto_download.h
@@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Data {
namespace AutoDownload {
-constexpr auto kMaxBytesLimit = 3000 * 512 * 1024;
+constexpr auto kMaxBytesLimit = 4000 * 512 * 1024;
enum class Source {
User = 0x00,
diff --git a/Telegram/SourceFiles/export/export_api_wrap.cpp b/Telegram/SourceFiles/export/export_api_wrap.cpp
index 1476b8ccc..c509f2a54 100644
--- a/Telegram/SourceFiles/export/export_api_wrap.cpp
+++ b/Telegram/SourceFiles/export/export_api_wrap.cpp
@@ -27,7 +27,7 @@ constexpr auto kFileNextRequestDelay = crl::time(20);
constexpr auto kChatsSliceLimit = 100;
constexpr auto kMessagesSliceLimit = 100;
constexpr auto kTopPeerSliceLimit = 100;
-constexpr auto kFileMaxSize = 1500 * 1024 * 1024;
+constexpr auto kFileMaxSize = 2000 * 1024 * 1024;
constexpr auto kLocationCacheSize = 100'000;
struct LocationKey {
diff --git a/Telegram/SourceFiles/export/export_settings.cpp b/Telegram/SourceFiles/export/export_settings.cpp
index 8c3ae84d0..58d92ce4a 100644
--- a/Telegram/SourceFiles/export/export_settings.cpp
+++ b/Telegram/SourceFiles/export/export_settings.cpp
@@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Export {
namespace {
-constexpr auto kMaxFileSize = 1500 * 1024 * 1024;
+constexpr auto kMaxFileSize = 2000 * 1024 * 1024;
} // namespace
diff --git a/Telegram/SourceFiles/export/view/export_view_settings.cpp b/Telegram/SourceFiles/export/view/export_view_settings.cpp
index e9dbc40af..c06e8e38c 100644
--- a/Telegram/SourceFiles/export/view/export_view_settings.cpp
+++ b/Telegram/SourceFiles/export/view/export_view_settings.cpp
@@ -88,21 +88,18 @@ int SizeLimitByIndex(int index) {
const auto megabytes = [&] {
if (index <= 10) {
return index;
- }
- else if (index <= 30) {
+ } else if (index <= 30) {
return 10 + (index - 10) * 2;
- }
- else if (index <= 40) {
+ } else if (index <= 40) {
return 50 + (index - 30) * 5;
- }
- else if (index <= 60) {
+ } else if (index <= 60) {
return 100 + (index - 40) * 10;
- }
- else if (index <= 70) {
+ } else if (index <= 70) {
return 300 + (index - 60) * 20;
- }
- else {
- return 500 + (index - 70) * 100;
+ } else if (index <= 80) {
+ return 500 + (index - 70) * 50;
+ } else {
+ return 1000 + (index - 80) * 100;
}
}();
return megabytes * kMegabyte;
diff --git a/Telegram/SourceFiles/export/view/export_view_settings.h b/Telegram/SourceFiles/export/view/export_view_settings.h
index 083828aeb..d8dc59224 100644
--- a/Telegram/SourceFiles/export/view/export_view_settings.h
+++ b/Telegram/SourceFiles/export/view/export_view_settings.h
@@ -25,7 +25,7 @@ class Session;
namespace Export {
namespace View {
-constexpr auto kSizeValueCount = 80;
+constexpr auto kSizeValueCount = 90;
int SizeLimitByIndex(int index);
class SettingsWidget : public Ui::RpWidget {
diff --git a/Telegram/SourceFiles/kotato/settings_menu.cpp b/Telegram/SourceFiles/kotato/settings_menu.cpp
index 47e88bd55..0b23863f9 100644
--- a/Telegram/SourceFiles/kotato/settings_menu.cpp
+++ b/Telegram/SourceFiles/kotato/settings_menu.cpp
@@ -437,12 +437,12 @@ void SetupKotatoSystem(
AddSkip(container);
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>(
container.get());
AddButton(
container,
- tr::ktg_settings_use_native_decorations(),
+ tr::lng_settings_native_frame(),
st::settingsButton
)->toggleOn(
useNativeDecorationsToggled->events_starting_with_copy(cUseNativeDecorations())
@@ -464,7 +464,7 @@ void SetupKotatoSystem(
confirmed,
cancelled));
}, container->lifetime());
-#endif // Q_OS_WIN || Q_OS_MAC || Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
+#endif // Q_OS_MAC
AddButton(
container,
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 60f4e9bd0..714a96ed0 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -2185,13 +2185,19 @@ void MainWidget::updateControlsGeometry() {
auto mainSectionWidth = width() - dialogsWidth - thirdSectionWidth;
_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) {
_thirdShadow->setGeometryToLeft(
width() - thirdSectionWidth - st::lineWidth,
- 0,
+ shadowTop,
st::lineWidth,
- height());
+ shadowHeight);
}
if (_callTopBar) {
_callTopBar->resizeToWidth(mainSectionWidth);
diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h
index fda60d0b7..63c30a66c 100644
--- a/Telegram/SourceFiles/mainwindow.h
+++ b/Telegram/SourceFiles/mainwindow.h
@@ -63,8 +63,6 @@ public:
void checkHistoryActivation();
- void fixOrder();
-
void sendPaths();
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
@@ -79,6 +77,7 @@ public:
void showMainMenu();
void updateTrayMenu(bool force = false) override;
+ void fixOrder() override;
void showSpecialLayer(
object_ptr layer,
diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp
index d3791830f..a18ac399c 100644
--- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp
+++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp
@@ -16,7 +16,7 @@ namespace Streaming {
namespace {
// 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) {
return (size > 0 && size <= kMaxFileSize) ? int(size) : 0;
diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp
index 7394753b8..06b35504e 100644
--- a/Telegram/SourceFiles/media/view/media_view_pip.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp
@@ -598,6 +598,7 @@ void PipPanel::mousePressEvent(QMouseEvent *e) {
if (e->button() != Qt::LeftButton) {
return;
}
+ updateOverState(e->pos());
_pressState = _overState;
_pressPoint = e->globalPos();
}
diff --git a/Telegram/SourceFiles/platform/linux/window_title_linux.h b/Telegram/SourceFiles/platform/linux/window_title_linux.h
index 19b2e9d06..c9e58bbe6 100644
--- a/Telegram/SourceFiles/platform/linux/window_title_linux.h
+++ b/Telegram/SourceFiles/platform/linux/window_title_linux.h
@@ -22,14 +22,22 @@ void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palet
namespace Platform {
-inline object_ptr CreateTitleWidget(QWidget *parent) {
+inline bool AllowNativeWindowFrameToggle() {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
- if (!DesktopEnvironment::IsUnity()) {
- return object_ptr(parent);
- }
+ return !DesktopEnvironment::IsUnity();
+#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
+ return false;
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
+}
- return { nullptr };
+inline object_ptr CreateTitleWidget(QWidget *parent) {
+ return AllowNativeWindowFrameToggle()
+ ? object_ptr(parent)
+ : object_ptr{ nullptr };
+}
+
+inline bool NativeTitleRequiresShadow() {
+ return false;
}
inline int PreviewTitleHeight() {
diff --git a/Telegram/SourceFiles/platform/mac/window_title_mac.h b/Telegram/SourceFiles/platform/mac/window_title_mac.h
index bf7370c08..924f7a440 100644
--- a/Telegram/SourceFiles/platform/mac/window_title_mac.h
+++ b/Telegram/SourceFiles/platform/mac/window_title_mac.h
@@ -32,8 +32,16 @@ private:
};
+inline bool AllowNativeWindowFrameToggle() {
+ return false;
+}
+
object_ptr CreateTitleWidget(QWidget *parent);
+inline bool NativeTitleRequiresShadow() {
+ return false;
+}
+
int PreviewTitleHeight();
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
diff --git a/Telegram/SourceFiles/platform/platform_window_title.h b/Telegram/SourceFiles/platform/platform_window_title.h
index 1af12c825..cd6b3a631 100644
--- a/Telegram/SourceFiles/platform/platform_window_title.h
+++ b/Telegram/SourceFiles/platform/platform_window_title.h
@@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform {
+bool AllowNativeWindowFrameToggle();
object_ptr CreateTitleWidget(QWidget *parent);
+bool NativeTitleRequiresShadow();
int PreviewTitleHeight();
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 {
-inline object_ptr CreateTitleWidget(QWidget *parent) {
+inline bool AllowNativeWindowFrameToggle() {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
- return object_ptr(parent);
+ return true;
+#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
+ return false;
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
+}
- return { nullptr };
+inline object_ptr CreateTitleWidget(QWidget *parent) {
+ return AllowNativeWindowFrameToggle()
+ ? object_ptr(parent)
+ : object_ptr{ nullptr };
+}
+
+inline bool NativeTitleRequiresShadow() {
+ return false;
}
inline int PreviewTitleHeight() {
diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp
index ef0ecbbd6..736993a20 100644
--- a/Telegram/SourceFiles/platform/win/main_window_win.cpp
+++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp
@@ -38,28 +38,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
#include
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#define max(a, b) ((a) < (b) ? (b) : (a))
-#include
-#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 &);
using namespace Microsoft::WRL;
@@ -112,515 +90,6 @@ HWND createTaskbarHider() {
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 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 _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 taskbarList;
bool handleSessionNotification = false;
@@ -638,13 +107,17 @@ MainWindow::MainWindow(not_null controller)
if (!_taskbarCreatedMsgId) {
_taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated");
}
- if (!UseNativeDecorations()) {
- subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
- if (update.paletteChanged()) {
- _psShadowWindows.setColor(st::windowShadowFg->c);
- }
- });
- }
+ subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
+ if (_shadow && update.paletteChanged()) {
+ _shadow->setColor(st::windowShadowFg->c);
+ }
+ });
+ Core::App().settings().nativeWindowFrameChanges(
+ ) | rpl::start_with_next([=] {
+ initShadows();
+ validateWindowTheme();
+ fixMaximizedWindow();
+ }, lifetime());
}
void MainWindow::TaskbarCreated() {
@@ -654,23 +127,21 @@ void MainWindow::TaskbarCreated() {
}
}
-void MainWindow::shadowsUpdate(ShadowsChanges changes, WINDOWPOS *position) {
- if (!UseNativeDecorations()) {
- _psShadowWindows.update(changes, position);
+void MainWindow::shadowsUpdate(
+ Ui::Platform::WindowShadow::Changes changes,
+ WINDOWPOS *position) {
+ if (_shadow) {
+ _shadow->update(changes, position);
}
}
void MainWindow::shadowsActivate() {
- if (!UseNativeDecorations()) {
-// _psShadowWindows.setColor(_shActive);
- shadowsUpdate(ShadowsChange::Activate);
- }
+// _shadow->setColor(_shActive);
+ shadowsUpdate(Ui::Platform::WindowShadow::Change::Activate);
}
void MainWindow::shadowsDeactivate() {
-// if (!UseNativeDecorations()) {
-// _psShadowWindows.setColor(_shInactive);
-// }
+// _shadow->setColor(_shInactive);
}
void MainWindow::psShowTrayMenu() {
@@ -768,6 +239,10 @@ void MainWindow::workmodeUpdated(DBIWorkMode mode) {
}
}
+void MainWindow::updateWindowIcon() {
+ updateIconCounters();
+}
+
void MainWindow::unreadCounterChangedHook() {
setWindowTitle(titleText());
updateIconCounters();
@@ -840,17 +315,22 @@ void MainWindow::initHook() {
}
void MainWindow::initShadows() {
- if (!UseNativeDecorations()) {
- _psShadowWindows.init(this, st::windowShadowFg->c);
- _shadowsWorking = true;
- psUpdateMargins();
- shadowsUpdate(ShadowsChange::Hidden);
+ if (Core::App().settings().nativeWindowFrame()) {
+ _shadow.reset();
+ } else {
+ _shadow.emplace(this, st::windowShadowFg->c);
}
+ updateCustomMargins();
+ firstShadowsUpdate();
}
void MainWindow::firstShadowsUpdate() {
- if (!UseNativeDecorations() && !(windowState() & Qt::WindowMinimized) && !isHidden()) {
- shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized | ShadowsChange::Shown);
+ using Change = Ui::Platform::WindowShadow::Change;
+ 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() {
- if (!ps_hWnd || _inUpdateMargins) return;
+void MainWindow::updateCustomMargins() {
+ if (!ps_hWnd || _inUpdateMargins) {
+ return;
+ }
_inUpdateMargins = true;
- RECT r, a;
+ const auto margins = computeCustomMargins();
+ if (const auto native = QGuiApplication::platformNativeInterface()) {
+ native->setWindowProperty(
+ windowHandle()->handle(),
+ qsl("WindowsCustomMargins"),
+ QVariant::fromValue(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);
- 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);
- 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) {
RECT w, m;
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);
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
}
+ return margins;
+}
- if (const auto native = QGuiApplication::platformNativeInterface()) {
- native->setWindowProperty(
- windowHandle()->handle(),
- qsl("WindowsCustomMargins"),
- QVariant::fromValue(margins));
+void MainWindow::validateWindowTheme() {
+ if (IsWindows8OrGreater()) {
+ return;
+ } else if (Dlls::SetWindowTheme != nullptr) {
+ 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()) {
- if (Dlls::SetWindowTheme != nullptr) {
- Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
- QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
- }
+}
+
+void MainWindow::fixMaximizedWindow() {
+ auto r = RECT();
+ GetClientRect(ps_hWnd, &r);
+ 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 {
@@ -1000,10 +517,6 @@ MainWindow::~MainWindow() {
if (ps_menu) DestroyMenu(ps_menu);
psDestroyIcons();
- if (!UseNativeDecorations()) {
- _shadowsWorking = false;
- _psShadowWindows.destroy();
- }
if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd);
EventFilter::Destroy();
diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h
index f599de881..d534f81e7 100644
--- a/Telegram/SourceFiles/platform/win/main_window_win.h
+++ b/Telegram/SourceFiles/platform/win/main_window_win.h
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#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/flags.h"
@@ -30,7 +31,9 @@ public:
void psInitSysMenu();
void updateSystemMenu(Qt::WindowState state);
- void psUpdateMargins();
+ void updateCustomMargins();
+
+ void updateWindowIcon() override;
void psRefreshTaskbarIcon();
@@ -42,22 +45,11 @@ public:
static void TaskbarCreated();
// Custom shadows.
- enum class ShadowsChange {
- Moved = (1 << 0),
- Resized = (1 << 1),
- Shown = (1 << 2),
- Hidden = (1 << 3),
- Activate = (1 << 4),
- };
- using ShadowsChanges = base::flags;
- friend inline constexpr auto is_flag_type(ShadowsChange) { return true; };
-
- bool shadowsWorking() const {
- return _shadowsWorking;
- }
void shadowsActivate();
void shadowsDeactivate();
- void shadowsUpdate(ShadowsChanges changes, WINDOWPOS *position = nullptr);
+ void shadowsUpdate(
+ Ui::Platform::WindowShadow::Changes changes,
+ WINDOWPOS *position = nullptr);
int deltaLeft() const {
return _deltaLeft;
@@ -99,12 +91,15 @@ protected:
private:
void updateIconCounters();
-
+ QMargins computeCustomMargins();
+ void validateWindowTheme();
void psDestroyIcons();
+ void fixMaximizedWindow();
static UINT _taskbarCreatedMsgId;
- bool _shadowsWorking = false;
+ std::optional _shadow;
+
bool _themeInited = false;
bool _inUpdateMargins = false;
diff --git a/Telegram/SourceFiles/platform/win/window_title_win.h b/Telegram/SourceFiles/platform/win/window_title_win.h
index 3423857a7..9508e508b 100644
--- a/Telegram/SourceFiles/platform/win/window_title_win.h
+++ b/Telegram/SourceFiles/platform/win/window_title_win.h
@@ -59,10 +59,18 @@ private:
};
+inline bool AllowNativeWindowFrameToggle() {
+ return true;
+}
+
inline object_ptr CreateTitleWidget(QWidget *parent) {
return object_ptr(parent);
}
+inline bool NativeTitleRequiresShadow() {
+ return true;
+}
+
inline int PreviewTitleHeight() {
return Window::Theme::DefaultPreviewTitleHeight();
}
diff --git a/Telegram/SourceFiles/platform/win/windows_event_filter.cpp b/Telegram/SourceFiles/platform/win/windows_event_filter.cpp
index 8a79abf64..6f0d8f901 100644
--- a/Telegram/SourceFiles/platform/win/windows_event_filter.cpp
+++ b/Telegram/SourceFiles/platform/win/windows_event_filter.cpp
@@ -78,56 +78,13 @@ bool EventFilter::nativeEventFilter(
});
}
-bool EventFilter::mainWindowEvent(
+bool EventFilter::customWindowFrameEvent(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam,
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) {
-
- 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: {
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
if (result) *result = 0;
@@ -162,47 +119,6 @@ bool EventFilter::mainWindowEvent(
}
} 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: {
if (!result) return false;
@@ -230,6 +146,103 @@ bool EventFilter::mainWindowEvent(
case WM_NCRBUTTONUP: {
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
} 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: {
if (wParam == SC_MOUSEMENU) {
diff --git a/Telegram/SourceFiles/platform/win/windows_event_filter.h b/Telegram/SourceFiles/platform/win/windows_event_filter.h
index 84ac63093..a0dbd9d1e 100644
--- a/Telegram/SourceFiles/platform/win/windows_event_filter.h
+++ b/Telegram/SourceFiles/platform/win/windows_event_filter.h
@@ -34,6 +34,13 @@ public:
private:
explicit EventFilter(not_null window);
+ bool customWindowFrameEvent(
+ HWND hWnd,
+ UINT msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ LRESULT *result);
+
not_null _window;
bool _sessionLoggedOff = false;
diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp
index 13aea7e84..7a822cd95 100644
--- a/Telegram/SourceFiles/settings/settings_advanced.cpp
+++ b/Telegram/SourceFiles/settings/settings_advanced.cpp
@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/about_box.h"
#include "boxes/confirm_box.h"
#include "platform/platform_specific.h"
+#include "platform/platform_window_title.h"
#include "base/platform/base_platform_info.h"
#include "window/window_session_controller.h"
#include "lang/lang_keys.h"
@@ -407,6 +408,20 @@ void SetupTrayContent(not_null container) {
}, 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()) {
const auto minimizedToggled = [] {
return cStartMinimized() && !Global::LocalPasscode();
diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp
index be4083834..d06ff0456 100644
--- a/Telegram/SourceFiles/storage/localimageloader.cpp
+++ b/Telegram/SourceFiles/storage/localimageloader.cpp
@@ -776,7 +776,7 @@ void FileLoadTask::process() {
}
_result->filesize = (int32)qMin(filesize, qint64(INT_MAX));
- if (!filesize || filesize > App::kFileSizeLimit) {
+ if (!filesize || filesize > kFileSizeLimit) {
return;
}
@@ -963,7 +963,7 @@ void FileLoadTask::finish() {
tr::lng_send_image_empty(tr::now, lt_name, _filepath)),
Ui::LayerOption::KeepOther);
removeFromAlbum();
- } else if (_result->filesize > App::kFileSizeLimit) {
+ } else if (_result->filesize > kFileSizeLimit) {
Ui::show(
Box(
tr::lng_send_image_too_large(tr::now, lt_name, _filepath)),
diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h
index 009d032db..200e46d0a 100644
--- a/Telegram/SourceFiles/storage/localimageloader.h
+++ b/Telegram/SourceFiles/storage/localimageloader.h
@@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/variant.h"
#include "api/api_common.h"
+constexpr auto kFileSizeLimit = 2000 * 1024 * 1024; // Load files up to 1500mb
+
enum class CompressConfirm {
Auto,
Yes,
diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp
index 2a05a4837..42a6c8355 100644
--- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp
+++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp
@@ -190,7 +190,7 @@ MimeDataState ComputeMimeDataState(const QMimeData *data) {
}
const auto filesize = info.size();
- if (filesize > App::kFileSizeLimit) {
+ if (filesize > kFileSizeLimit) {
return MimeDataState::None;
} else if (allAreSmallImages) {
if (filesize > App::kImageSizeLimit) {
@@ -237,7 +237,7 @@ PreparedList PrepareMediaList(const QStringList &files, int previewWidth) {
PreparedList::Error::EmptyFile,
file
};
- } else if (filesize > App::kFileSizeLimit) {
+ } else if (filesize > kFileSizeLimit) {
return {
PreparedList::Error::TooLargeFile,
file
diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp
index d0f83c6f3..0fde90a9b 100644
--- a/Telegram/SourceFiles/window/main_window.cpp
+++ b/Telegram/SourceFiles/window/main_window.cpp
@@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/crc32hash.h"
#include "base/call_delayed.h"
#include "ui/toast/toast.h"
+#include "ui/widgets/shadow.h"
#include "ui/ui_utility.h"
#include "apiwrap.h"
#include "mainwindow.h"
@@ -265,9 +266,14 @@ void MainWindow::init() {
updatePalette();
- if (!UseNativeDecorations() && (_title = Platform::CreateTitleWidget(this))) {
- _title->init();
+ if (Platform::AllowNativeWindowFrameToggle()) {
+ Core::App().settings().nativeWindowFrameChanges(
+ ) | rpl::start_with_next([=](bool native) {
+ refreshTitleWidget();
+ recountGeometryConstraints();
+ }, lifetime());
}
+ refreshTitleWidget();
initSize();
updateUnreadCounter();
@@ -340,9 +346,34 @@ int MainWindow::computeMinHeight() const {
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());
setMinimumHeight(computeMinHeight());
+}
+
+void MainWindow::recountGeometryConstraints() {
+ updateMinimumSize();
+ updateControlsGeometry();
+ fixOrder();
+}
+
+void MainWindow::initSize() {
+ updateMinimumSize();
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)));
@@ -455,6 +486,9 @@ void MainWindow::updateControlsGeometry() {
_title->setGeometry(0, bodyTop, width(), _title->height());
bodyTop += _title->height();
}
+ if (_titleShadow) {
+ _titleShadow->setGeometry(0, bodyTop, width(), st::lineWidth);
+ }
if (_outdated) {
Ui::SendPendingMoveResizeEvents(_outdated.data());
_outdated->resizeToWidth(width());
@@ -637,6 +671,8 @@ void MainWindow::launchDrag(std::unique_ptr data) {
}
}
-MainWindow::~MainWindow() = default;
+MainWindow::~MainWindow() {
+ _title.destroy();
+}
} // namespace Window
diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h
index 30dee3d1f..5d09511cb 100644
--- a/Telegram/SourceFiles/window/main_window.h
+++ b/Telegram/SourceFiles/window/main_window.h
@@ -21,6 +21,7 @@ class Account;
namespace Ui {
class BoxContent;
+class PlainShadow;
} // namespace Ui
namespace Window {
@@ -81,6 +82,8 @@ public:
virtual void updateTrayMenu(bool force = false) {
}
+ virtual void fixOrder() {
+ }
virtual ~MainWindow();
@@ -102,6 +105,7 @@ public:
int computeMinWidth() const;
int computeMinHeight() const;
+ void recountGeometryConstraints();
virtual void updateControlsGeometry();
public slots:
@@ -174,6 +178,8 @@ protected:
void updateUnreadCounter();
private:
+ void refreshTitleWidget();
+ void updateMinimumSize();
void updatePalette();
void initSize();
@@ -185,6 +191,7 @@ private:
bool _positionInited = false;
object_ptr _title = { nullptr };
+ object_ptr _titleShadow = { nullptr };
object_ptr _outdated;
object_ptr _body;
object_ptr _rightColumn = { nullptr };
diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp
index fce4b134d..a4fcc127c 100644
--- a/Telegram/SourceFiles/window/window_controller.cpp
+++ b/Telegram/SourceFiles/window/window_controller.cpp
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_updates.h"
#include "core/application.h"
#include "core/click_handler_types.h"
+#include "platform/platform_window_title.h"
#include "main/main_account.h"
#include "main/main_domain.h"
#include "main/main_session.h"
@@ -241,6 +242,13 @@ void Controller::showSettings() {
_widget.showSettings();
}
+int Controller::verticalShadowTop() const {
+ return (Platform::NativeTitleRequiresShadow()
+ && Core::App().settings().nativeWindowFrame())
+ ? st::lineWidth
+ : 0;
+}
+
void Controller::showToast(const QString &text) {
Ui::Toast::Show(_widget.bodyWidget(), text);
}
@@ -257,9 +265,7 @@ void Controller::showRightColumn(object_ptr widget) {
}
void Controller::sideBarChanged() {
- _widget.setMinimumWidth(_widget.computeMinWidth());
- _widget.updateControlsGeometry();
- _widget.fixOrder();
+ _widget.recountGeometryConstraints();
}
void Controller::activate() {
diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h
index e5f14096f..05c6e02fd 100644
--- a/Telegram/SourceFiles/window/window_controller.h
+++ b/Telegram/SourceFiles/window/window_controller.h
@@ -48,6 +48,8 @@ public:
void showSettings();
+ [[nodiscard]] int verticalShadowTop() const;
+
template
QPointer show(
object_ptr content,
diff --git a/Telegram/SourceFiles/window/window_title_qt.cpp b/Telegram/SourceFiles/window/window_title_qt.cpp
index e9417d03c..555a87355 100644
--- a/Telegram/SourceFiles/window/window_title_qt.cpp
+++ b/Telegram/SourceFiles/window/window_title_qt.cpp
@@ -10,11 +10,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h"
#include "styles/style_window.h"
+#include "base/call_delayed.h"
#include
#include
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)
: TitleWidget(parent)
@@ -45,11 +55,35 @@ TitleWidgetQt::TitleWidgetQt(QWidget *parent)
QCoreApplication::instance()->installEventFilter(this);
- window()->setWindowFlag(Qt::FramelessWindowHint, true);
+ _windowWasFrameless = (window()->windowFlags() & Qt::FramelessWindowHint) != 0;
+ if (!_windowWasFrameless) {
+ toggleFramelessWindow(true);
+ }
setAttribute(Qt::WA_OpaquePaintEvent);
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() {
connect(
window()->windowHandle(),
@@ -103,7 +137,7 @@ void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) {
bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::MouseMove
|| e->type() == QEvent::MouseButtonPress) {
- if(window()->isAncestorOf(static_cast(obj))) {
+ if (window()->isAncestorOf(static_cast(obj))) {
const auto mouseEvent = static_cast(e);
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint());
@@ -111,7 +145,7 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
updateCursor(edges);
}
- if(e->type() == QEvent::MouseButtonPress
+ if (e->type() == QEvent::MouseButtonPress
&& mouseEvent->button() == Qt::LeftButton
&& window()->windowState() != Qt::WindowMaximized) {
return startResize(edges);
@@ -119,9 +153,7 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
}
} else if (e->type() == QEvent::Leave) {
if (window() == static_cast(obj)) {
- while (QGuiApplication::overrideCursor()) {
- QGuiApplication::restoreOverrideCursor();
- }
+ restoreCursor();
}
}
@@ -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) {
if (!edges || window()->windowState() == Qt::WindowMaximized) {
- while (QGuiApplication::overrideCursor()) {
- QGuiApplication::restoreOverrideCursor();
- }
-
+ restoreCursor();
return;
} else if (!QGuiApplication::overrideCursor()) {
+ _cursorOverriden = false;
+ }
+ if (!_cursorOverriden) {
+ _cursorOverriden = true;
QGuiApplication::setOverrideCursor(QCursor());
}
diff --git a/Telegram/SourceFiles/window/window_title_qt.h b/Telegram/SourceFiles/window/window_title_qt.h
index 68d4dcbce..67a80945a 100644
--- a/Telegram/SourceFiles/window/window_title_qt.h
+++ b/Telegram/SourceFiles/window/window_title_qt.h
@@ -24,6 +24,7 @@ namespace Window {
class TitleWidgetQt : public TitleWidget {
public:
TitleWidgetQt(QWidget *parent);
+ ~TitleWidgetQt();
void init() override;
@@ -40,8 +41,10 @@ private:
void updateButtonsState();
void updateControlsPosition();
+ void toggleFramelessWindow(bool enabled);
Qt::Edges edgesFromPos(const QPoint &pos);
void updateCursor(Qt::Edges edges);
+ void restoreCursor();
bool startResize(Qt::Edges edges);
const style::WindowTitle &_st;
@@ -52,6 +55,8 @@ private:
bool _maximizedState = false;
bool _activeState = false;
+ bool _windowWasFrameless = false;
+ bool _cursorOverriden = false;
};
diff --git a/Telegram/build/version b/Telegram/build/version
index 9c3b3678c..85b4d4726 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 2001017
+AppVersion 2001018
AppVersionStrMajor 2.1
-AppVersionStrSmall 2.1.17
-AppVersionStr 2.1.17
+AppVersionStrSmall 2.1.18
+AppVersionStr 2.1.18
BetaChannel 1
AlphaVersion 0
-AppVersionOriginal 2.1.17.beta
+AppVersionOriginal 2.1.18.beta
diff --git a/Telegram/lib_ui b/Telegram/lib_ui
index 11a39d9d9..c262a0931 160000
--- a/Telegram/lib_ui
+++ b/Telegram/lib_ui
@@ -1 +1 @@
-Subproject commit 11a39d9d941e4cd1c60a0c97352cbf89700f42fc
+Subproject commit c262a0931e4b32ff156aa12cb2657c8cdd444c69
diff --git a/changelog.txt b/changelog.txt
index f09a71aae..bc25a3a85 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -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)
- Fix messages editing in a non-active account.