mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-17 21:36:54 +00:00
Save IV window geometry.
This commit is contained in:
parent
d9ed3a7d3f
commit
fd833dff35
@ -995,6 +995,8 @@ PRIVATE
|
||||
intro/intro_step.h
|
||||
intro/intro_widget.cpp
|
||||
intro/intro_widget.h
|
||||
iv/iv_delegate_impl.cpp
|
||||
iv/iv_delegate_impl.h
|
||||
iv/iv_instance.cpp
|
||||
iv/iv_instance.h
|
||||
lang/lang_cloud_manager.cpp
|
||||
|
@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_updates.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "countries/countries_manager.h"
|
||||
#include "iv/iv_delegate_impl.h"
|
||||
#include "iv/iv_instance.h"
|
||||
#include "lang/lang_file_parser.h"
|
||||
#include "lang/lang_translator.h"
|
||||
@ -163,7 +164,8 @@ Application::Application()
|
||||
, _domain(std::make_unique<Main::Domain>(cDataFile()))
|
||||
, _exportManager(std::make_unique<Export::Manager>())
|
||||
, _calls(std::make_unique<Calls::Instance>())
|
||||
, _iv(std::make_unique<Iv::Instance>())
|
||||
, _iv(std::make_unique<Iv::Instance>(
|
||||
Ui::CreateChild<Iv::DelegateImpl>(this)))
|
||||
, _langpack(std::make_unique<Lang::Instance>())
|
||||
, _langCloudManager(std::make_unique<Lang::CloudManager>(langpack()))
|
||||
, _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>())
|
||||
@ -1368,6 +1370,25 @@ Window::Controller *Application::windowFor(
|
||||
return activePrimaryWindow();
|
||||
}
|
||||
|
||||
Window::Controller *Application::findWindow(
|
||||
not_null<QWidget*> widget) const {
|
||||
const auto window = widget->window();
|
||||
if (_lastActiveWindow && _lastActiveWindow->widget() == window) {
|
||||
return _lastActiveWindow;
|
||||
}
|
||||
for (const auto &[account, primary] : _primaryWindows) {
|
||||
if (primary->widget() == window) {
|
||||
return primary.get();
|
||||
}
|
||||
}
|
||||
for (const auto &[history, secondary] : _secondaryWindows) {
|
||||
if (secondary->widget() == window) {
|
||||
return secondary.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Window::Controller *Application::activeWindow() const {
|
||||
return _lastActiveWindow;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ class Session;
|
||||
|
||||
namespace Iv {
|
||||
class Instance;
|
||||
class DelegateImpl;
|
||||
} // namespace Iv
|
||||
|
||||
namespace Ui {
|
||||
@ -165,6 +166,8 @@ public:
|
||||
bool hasActiveWindow(not_null<Main::Session*> session) const;
|
||||
[[nodiscard]] bool savingPositionFor(
|
||||
not_null<Window::Controller*> window) const;
|
||||
[[nodiscard]] Window::Controller *findWindow(
|
||||
not_null<QWidget*> widget) const;
|
||||
[[nodiscard]] Window::Controller *activeWindow() const;
|
||||
[[nodiscard]] Window::Controller *activePrimaryWindow() const;
|
||||
[[nodiscard]] Window::Controller *separateWindowForAccount(
|
||||
|
@ -134,6 +134,8 @@ QByteArray Settings::serialize() const {
|
||||
LogPosition(_windowPosition, u"Window"_q);
|
||||
const auto mediaViewPosition = Serialize(_mediaViewPosition);
|
||||
LogPosition(_mediaViewPosition, u"Viewer"_q);
|
||||
const auto ivPosition = Serialize(_ivPosition);
|
||||
LogPosition(_ivPosition, u"IV"_q);
|
||||
const auto proxy = _proxy.serialize();
|
||||
const auto skipLanguages = _skipTranslationLanguages.current();
|
||||
|
||||
@ -209,7 +211,8 @@ QByteArray Settings::serialize() const {
|
||||
+ Serialize::stringSize(_playbackDeviceId.current())
|
||||
+ Serialize::stringSize(_captureDeviceId.current())
|
||||
+ Serialize::stringSize(_callPlaybackDeviceId.current())
|
||||
+ Serialize::stringSize(_callCaptureDeviceId.current());
|
||||
+ Serialize::stringSize(_callCaptureDeviceId.current())
|
||||
+ Serialize::bytearraySize(ivPosition);
|
||||
|
||||
auto result = QByteArray();
|
||||
result.reserve(size);
|
||||
@ -353,7 +356,8 @@ QByteArray Settings::serialize() const {
|
||||
<< _playbackDeviceId.current()
|
||||
<< _captureDeviceId.current()
|
||||
<< _callPlaybackDeviceId.current()
|
||||
<< _callCaptureDeviceId.current();
|
||||
<< _callCaptureDeviceId.current()
|
||||
<< ivPosition;
|
||||
}
|
||||
|
||||
Ensures(result.size() == size);
|
||||
@ -469,6 +473,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||
base::flat_set<QString> recentEmojiSkip;
|
||||
qint32 trayIconMonochrome = (_trayIconMonochrome.current() ? 1 : 0);
|
||||
qint32 ttlVoiceClickTooltipHidden = _ttlVoiceClickTooltipHidden.current() ? 1 : 0;
|
||||
QByteArray ivPosition;
|
||||
|
||||
stream >> themesAccentColors;
|
||||
if (!stream.atEnd()) {
|
||||
@ -747,6 +752,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||
? QString()
|
||||
: legacyCallCaptureDeviceId;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> ivPosition;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: "
|
||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||
@ -945,6 +953,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||
_recentEmojiSkip = std::move(recentEmojiSkip);
|
||||
_trayIconMonochrome = (trayIconMonochrome == 1);
|
||||
_ttlVoiceClickTooltipHidden = (ttlVoiceClickTooltipHidden == 1);
|
||||
if (!ivPosition.isEmpty()) {
|
||||
_ivPosition = Deserialize(ivPosition);
|
||||
}
|
||||
}
|
||||
|
||||
QString Settings::getSoundPath(const QString &key) const {
|
||||
|
@ -863,6 +863,13 @@ public:
|
||||
_ttlVoiceClickTooltipHidden = value;
|
||||
}
|
||||
|
||||
[[nodiscard]] const WindowPosition &ivPosition() const {
|
||||
return _ivPosition;
|
||||
}
|
||||
void setIvPosition(const WindowPosition &position) {
|
||||
_ivPosition = position;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool ThirdColumnByDefault();
|
||||
[[nodiscard]] static float64 DefaultDialogsWidthRatio();
|
||||
|
||||
@ -990,6 +997,7 @@ private:
|
||||
std::optional<uint64> _macRoundIconDigest;
|
||||
rpl::variable<bool> _storiesClickTooltipHidden = false;
|
||||
rpl::variable<bool> _ttlVoiceClickTooltipHidden = false;
|
||||
WindowPosition _ivPosition;
|
||||
|
||||
bool _tabbedReplacedWithInfo = false; // per-window
|
||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
||||
|
@ -127,7 +127,7 @@ constexpr auto kMaxOriginalEntryLines = 8192;
|
||||
if (const auto controller = my.sessionWindow.get()) {
|
||||
if (const auto iv = webpage->iv.get()) {
|
||||
const auto hash = ExtractHash(webpage, text);
|
||||
Core::App().iv().show(controller->uiShow(), iv, hash);
|
||||
Core::App().iv().show(controller, iv, hash);
|
||||
return;
|
||||
} else {
|
||||
HiddenUrlClickHandler::Open(webpage->url, context.other);
|
||||
|
@ -194,8 +194,11 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
Controller::Controller(Fn<ShareBoxResult(ShareBoxDescriptor)> showShareBox)
|
||||
: _updateStyles([=] {
|
||||
Controller::Controller(
|
||||
not_null<Delegate*> delegate,
|
||||
Fn<ShareBoxResult(ShareBoxDescriptor)> showShareBox)
|
||||
: _delegate(delegate)
|
||||
, _updateStyles([=] {
|
||||
const auto str = EscapeForScriptString(ComputeStyles());
|
||||
if (_webview) {
|
||||
_webview->eval("IV.updateStyles('" + str + "');");
|
||||
@ -359,9 +362,15 @@ void Controller::createWindow() {
|
||||
updateTitleGeometry(width);
|
||||
}, _subtitle->lifetime());
|
||||
|
||||
window->setGeometry({ 200, 200, 600, 800 });
|
||||
window->setGeometry(_delegate->ivGeometry());
|
||||
window->setMinimumSize({ st::windowMinWidth, st::windowMinHeight });
|
||||
|
||||
window->geometryValue(
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::skip(1) | rpl::start_with_next([=] {
|
||||
_delegate->ivSaveGeometry(window);
|
||||
}, window->lifetime());
|
||||
|
||||
_container = Ui::CreateChild<Ui::RpWidget>(window->window());
|
||||
rpl::combine(
|
||||
window->sizeValue(),
|
||||
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "base/invoke_queued.h"
|
||||
#include "base/object_ptr.h"
|
||||
#include "base/unique_qptr.h"
|
||||
#include "iv/iv_delegate.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/text/text.h"
|
||||
|
||||
@ -46,7 +47,9 @@ struct ShareBoxDescriptor {
|
||||
|
||||
class Controller final {
|
||||
public:
|
||||
explicit Controller(Fn<ShareBoxResult(ShareBoxDescriptor)> showShareBox);
|
||||
Controller(
|
||||
not_null<Delegate*> delegate,
|
||||
Fn<ShareBoxResult(ShareBoxDescriptor)> showShareBox);
|
||||
~Controller();
|
||||
|
||||
struct Event {
|
||||
@ -115,6 +118,8 @@ private:
|
||||
void showShareMenu();
|
||||
void destroyShareMenu();
|
||||
|
||||
const not_null<Delegate*> _delegate;
|
||||
|
||||
std::unique_ptr<Ui::RpWindow> _window;
|
||||
std::unique_ptr<Ui::RpWidget> _subtitleWrap;
|
||||
rpl::variable<QString> _subtitleText;
|
||||
|
19
Telegram/SourceFiles/iv/iv_delegate.h
Normal file
19
Telegram/SourceFiles/iv/iv_delegate.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Iv {
|
||||
|
||||
class Delegate {
|
||||
public:
|
||||
virtual void ivSetLastSourceWindow(not_null<QWidget*> window) = 0;
|
||||
[[nodiscard]] virtual QRect ivGeometry() const = 0;
|
||||
virtual void ivSaveGeometry(not_null<QWidget*> window) = 0;
|
||||
};
|
||||
|
||||
} // namespace Iv
|
120
Telegram/SourceFiles/iv/iv_delegate_impl.cpp
Normal file
120
Telegram/SourceFiles/iv/iv_delegate_impl.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "iv/iv_delegate_impl.h"
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "mainwindow.h"
|
||||
#include "window/main_window.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QWindow>
|
||||
|
||||
namespace Iv {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] Core::WindowPosition DefaultPosition() {
|
||||
auto center = qApp->primaryScreen()->geometry().center();
|
||||
const auto moncrc = [&] {
|
||||
if (const auto active = Core::App().activeWindow()) {
|
||||
const auto widget = active->widget();
|
||||
center = widget->geometry().center();
|
||||
if (const auto screen = widget->screen()) {
|
||||
return Platform::ScreenNameChecksum(screen->name());
|
||||
}
|
||||
}
|
||||
return Core::App().settings().windowPosition().moncrc;
|
||||
}();
|
||||
return {
|
||||
.moncrc = moncrc,
|
||||
.scale = cScale(),
|
||||
.x = (center.x() - st::ivWidthDefault / 2),
|
||||
.y = (center.y() - st::ivHeightDefault / 2),
|
||||
.w = st::ivWidthDefault,
|
||||
.h = st::ivHeightDefault,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DelegateImpl::ivSetLastSourceWindow(not_null<QWidget*> window) {
|
||||
_lastSourceWindow = window;
|
||||
}
|
||||
|
||||
QRect DelegateImpl::ivGeometry() const {
|
||||
const auto found = _lastSourceWindow
|
||||
? Core::App().findWindow(_lastSourceWindow)
|
||||
: nullptr;
|
||||
|
||||
const auto saved = Core::App().settings().ivPosition();
|
||||
const auto adjusted = Core::AdjustToScale(saved, u"IV"_q);
|
||||
const auto initial = DefaultPosition();
|
||||
auto result = initial.rect();
|
||||
if (const auto window = found ? found : Core::App().activeWindow()) {
|
||||
result = window->widget()->countInitialGeometry(
|
||||
adjusted,
|
||||
initial,
|
||||
{ st::ivWidthMin, st::ivHeightMin });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DelegateImpl::ivSaveGeometry(not_null<QWidget*> window) {
|
||||
if (!window->windowHandle()) {
|
||||
return;
|
||||
}
|
||||
const auto state = window->windowHandle()->windowState();
|
||||
if (state == Qt::WindowMinimized) {
|
||||
return;
|
||||
}
|
||||
const auto &savedPosition = Core::App().settings().ivPosition();
|
||||
auto realPosition = savedPosition;
|
||||
if (state == Qt::WindowMaximized) {
|
||||
realPosition.maximized = 1;
|
||||
realPosition.moncrc = 0;
|
||||
DEBUG_LOG(("IV Pos: Saving maximized position."));
|
||||
} else {
|
||||
auto r = window->geometry();
|
||||
realPosition.x = r.x();
|
||||
realPosition.y = r.y();
|
||||
realPosition.w = r.width();
|
||||
realPosition.h = r.height();
|
||||
realPosition.scale = cScale();
|
||||
realPosition.maximized = 0;
|
||||
realPosition.moncrc = 0;
|
||||
DEBUG_LOG(("IV Pos: "
|
||||
"Saving non-maximized position: %1, %2, %3, %4"
|
||||
).arg(realPosition.x
|
||||
).arg(realPosition.y
|
||||
).arg(realPosition.w
|
||||
).arg(realPosition.h));
|
||||
}
|
||||
realPosition = Window::PositionWithScreen(
|
||||
realPosition,
|
||||
window,
|
||||
{ st::ivWidthMin, st::ivHeightMin });
|
||||
if (realPosition.w >= st::ivWidthMin
|
||||
&& realPosition.h >= st::ivHeightMin
|
||||
&& realPosition != savedPosition) {
|
||||
DEBUG_LOG(("IV Pos: "
|
||||
"Writing: %1, %2, %3, %4 (scale %5%, maximized %6)")
|
||||
.arg(realPosition.x)
|
||||
.arg(realPosition.y)
|
||||
.arg(realPosition.w)
|
||||
.arg(realPosition.h)
|
||||
.arg(realPosition.scale)
|
||||
.arg(Logs::b(realPosition.maximized)));
|
||||
Core::App().settings().setIvPosition(realPosition);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Iv
|
27
Telegram/SourceFiles/iv/iv_delegate_impl.h
Normal file
27
Telegram/SourceFiles/iv/iv_delegate_impl.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "iv/iv_delegate.h"
|
||||
|
||||
namespace Iv {
|
||||
|
||||
class DelegateImpl final : public Delegate {
|
||||
public:
|
||||
DelegateImpl() = default;
|
||||
|
||||
void ivSetLastSourceWindow(not_null<QWidget*> window) override;
|
||||
[[nodiscard]] QRect ivGeometry() const override;
|
||||
void ivSaveGeometry(not_null<QWidget*> window) override;
|
||||
|
||||
private:
|
||||
QPointer<QWidget> _lastSourceWindow;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Iv
|
@ -62,6 +62,7 @@ constexpr auto kKeepLoadingParts = 8;
|
||||
class Shown final : public base::has_weak_ptr {
|
||||
public:
|
||||
Shown(
|
||||
not_null<Delegate*> delegate,
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
not_null<Data*> data,
|
||||
QString hash);
|
||||
@ -143,6 +144,7 @@ private:
|
||||
int64 total = 0);
|
||||
void requestFail(Webview::DataRequest request);
|
||||
|
||||
const not_null<Delegate*> _delegate;
|
||||
const not_null<Main::Session*> _session;
|
||||
std::shared_ptr<Main::SessionShow> _show;
|
||||
QString _id;
|
||||
@ -166,10 +168,12 @@ private:
|
||||
};
|
||||
|
||||
Shown::Shown(
|
||||
not_null<Delegate*> delegate,
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
not_null<Data*> data,
|
||||
QString hash)
|
||||
: _session(&show->session())
|
||||
: _delegate(delegate)
|
||||
, _session(&show->session())
|
||||
, _show(show) {
|
||||
prepare(data, hash);
|
||||
}
|
||||
@ -398,7 +402,9 @@ void Shown::createController() {
|
||||
const auto showShareBox = [=](ShareBoxDescriptor &&descriptor) {
|
||||
return shareBox(std::move(descriptor));
|
||||
};
|
||||
_controller = std::make_unique<Controller>(std::move(showShareBox));
|
||||
_controller = std::make_unique<Controller>(
|
||||
_delegate,
|
||||
std::move(showShareBox));
|
||||
|
||||
_controller->events(
|
||||
) | rpl::start_to_stream(_events, _controller->lifetime());
|
||||
@ -795,10 +801,19 @@ void Shown::minimize() {
|
||||
}
|
||||
}
|
||||
|
||||
Instance::Instance() = default;
|
||||
Instance::Instance(not_null<Delegate*> delegate) : _delegate(delegate) {
|
||||
}
|
||||
|
||||
Instance::~Instance() = default;
|
||||
|
||||
void Instance::show(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Data*> data,
|
||||
QString hash) {
|
||||
_delegate->ivSetLastSourceWindow(controller->widget());
|
||||
show(controller->uiShow(), data, hash);
|
||||
}
|
||||
|
||||
void Instance::show(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
not_null<Data*> data,
|
||||
@ -813,7 +828,7 @@ void Instance::show(
|
||||
_shown->moveTo(data, hash);
|
||||
return;
|
||||
}
|
||||
_shown = std::make_unique<Shown>(show, data, hash);
|
||||
_shown = std::make_unique<Shown>(_delegate, show, data, hash);
|
||||
_shownSession = session;
|
||||
_shown->events() | rpl::start_with_next([=](Controller::Event event) {
|
||||
using Type = Controller::Event::Type;
|
||||
|
@ -7,11 +7,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "iv/iv_delegate.h"
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
class SessionShow;
|
||||
} // namespace Main
|
||||
|
||||
namespace Window {
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
namespace Iv {
|
||||
|
||||
class Data;
|
||||
@ -19,9 +25,13 @@ class Shown;
|
||||
|
||||
class Instance final {
|
||||
public:
|
||||
Instance();
|
||||
explicit Instance(not_null<Delegate*> delegate);
|
||||
~Instance();
|
||||
|
||||
void show(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Data*> data,
|
||||
QString hash);
|
||||
void show(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
not_null<Data*> data,
|
||||
@ -42,6 +52,8 @@ private:
|
||||
void processJoinChannel(const QString &context);
|
||||
void requestFull(not_null<Main::Session*> session, const QString &id);
|
||||
|
||||
const not_null<Delegate*> _delegate;
|
||||
|
||||
std::unique_ptr<Shown> _shown;
|
||||
Main::Session *_shownSession = nullptr;
|
||||
base::flat_set<not_null<Main::Session*>> _tracking;
|
||||
|
@ -319,6 +319,11 @@ windowArchiveToast: Toast(defaultToast) {
|
||||
maxWidth: boxWideWidth;
|
||||
}
|
||||
|
||||
ivWidthMin: 380px;
|
||||
ivHeightMin: 480px;
|
||||
ivWidthDefault: 600px;
|
||||
ivHeightDefault: 800px;
|
||||
|
||||
// Windows specific
|
||||
|
||||
winQuitIcon: icon {{ "win_quit", windowFg }};
|
||||
|
@ -15,6 +15,7 @@ PRIVATE
|
||||
iv/iv_controller.h
|
||||
iv/iv_data.cpp
|
||||
iv/iv_data.h
|
||||
iv/iv_delegate.h
|
||||
iv/iv_pch.h
|
||||
iv/iv_prepare.cpp
|
||||
iv/iv_prepare.h
|
||||
|
Loading…
Reference in New Issue
Block a user