mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Initial implementation of windowed media viewer on macOS.
This commit is contained in:
parent
7a5c9a6fb8
commit
2a1e3c4453
11 changed files with 475 additions and 41 deletions
|
@ -1083,6 +1083,7 @@ PRIVATE
|
||||||
platform/linux/notifications_manager_linux_dummy.cpp
|
platform/linux/notifications_manager_linux_dummy.cpp
|
||||||
platform/linux/notifications_manager_linux.cpp
|
platform/linux/notifications_manager_linux.cpp
|
||||||
platform/linux/notifications_manager_linux.h
|
platform/linux/notifications_manager_linux.h
|
||||||
|
platform/linux/overlay_widget_linux.h
|
||||||
platform/linux/specific_linux.cpp
|
platform/linux/specific_linux.cpp
|
||||||
platform/linux/specific_linux.h
|
platform/linux/specific_linux.h
|
||||||
platform/linux/tray_linux.cpp
|
platform/linux/tray_linux.cpp
|
||||||
|
@ -1098,6 +1099,8 @@ PRIVATE
|
||||||
platform/mac/main_window_mac.h
|
platform/mac/main_window_mac.h
|
||||||
platform/mac/notifications_manager_mac.mm
|
platform/mac/notifications_manager_mac.mm
|
||||||
platform/mac/notifications_manager_mac.h
|
platform/mac/notifications_manager_mac.h
|
||||||
|
platform/mac/overlay_widget_mac.h
|
||||||
|
platform/mac/overlay_widget_mac.mm
|
||||||
platform/mac/specific_mac.mm
|
platform/mac/specific_mac.mm
|
||||||
platform/mac/specific_mac.h
|
platform/mac/specific_mac.h
|
||||||
platform/mac/specific_mac_p.mm
|
platform/mac/specific_mac_p.mm
|
||||||
|
@ -1135,6 +1138,7 @@ PRIVATE
|
||||||
platform/win/main_window_win.h
|
platform/win/main_window_win.h
|
||||||
platform/win/notifications_manager_win.cpp
|
platform/win/notifications_manager_win.cpp
|
||||||
platform/win/notifications_manager_win.h
|
platform/win/notifications_manager_win.h
|
||||||
|
platform/win/overlay_widget_win.h
|
||||||
platform/win/specific_win.cpp
|
platform/win/specific_win.cpp
|
||||||
platform/win/specific_win.h
|
platform/win/specific_win.h
|
||||||
platform/win/tray_win.cpp
|
platform/win/tray_win.cpp
|
||||||
|
@ -1154,6 +1158,8 @@ PRIVATE
|
||||||
platform/platform_integration.h
|
platform/platform_integration.h
|
||||||
platform/platform_main_window.h
|
platform/platform_main_window.h
|
||||||
platform/platform_notifications_manager.h
|
platform/platform_notifications_manager.h
|
||||||
|
platform/platform_overlay_widget.cpp
|
||||||
|
platform/platform_overlay_widget.h
|
||||||
platform/platform_specific.h
|
platform/platform_specific.h
|
||||||
platform/platform_tray.h
|
platform/platform_tray.h
|
||||||
platform/platform_window_title.h
|
platform/platform_window_title.h
|
||||||
|
|
|
@ -81,6 +81,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/main_session_settings.h"
|
#include "main/main_session_settings.h"
|
||||||
#include "layout/layout_document_generic_preview.h"
|
#include "layout/layout_document_generic_preview.h"
|
||||||
|
#include "platform/platform_overlay_widget.h"
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
#include "storage/storage_account.h"
|
#include "storage/storage_account.h"
|
||||||
#include "calls/calls_instance.h"
|
#include "calls/calls_instance.h"
|
||||||
|
@ -298,15 +299,12 @@ OverlayWidget::PipWrap::PipWrap(
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayWidget::OverlayWidget()
|
OverlayWidget::OverlayWidget()
|
||||||
: _supportWindowMode(!Platform::IsMac())
|
: _supportWindowMode(true)
|
||||||
, _wrap(std::make_unique<Ui::GL::Window>())
|
, _wrap(std::make_unique<Ui::GL::Window>())
|
||||||
, _window(_wrap->window())
|
, _window(_wrap->window())
|
||||||
#ifndef Q_OS_MAC
|
, _helper(Platform::CreateOverlayWidgetHelper(_window.get(), [=](bool maximized) {
|
||||||
, _controls(Ui::Platform::SetupSeparateTitleControls(
|
toggleFullScreen(maximized);
|
||||||
_window.get(),
|
}))
|
||||||
st::callTitle,
|
|
||||||
[=](bool maximized) { toggleFullScreen(maximized); }))
|
|
||||||
#endif
|
|
||||||
, _body(_wrap->widget())
|
, _body(_wrap->widget())
|
||||||
, _surface(
|
, _surface(
|
||||||
Ui::GL::CreateSurface(_body, chooseRenderer(_wrap->backend())))
|
Ui::GL::CreateSurface(_body, chooseRenderer(_wrap->backend())))
|
||||||
|
@ -489,22 +487,17 @@ OverlayWidget::OverlayWidget()
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::orderWidgets() {
|
void OverlayWidget::orderWidgets() {
|
||||||
#ifndef Q_OS_MAC
|
_helper->orderWidgets();
|
||||||
_controls->wrap.raise();
|
|
||||||
#endif // !Q_OS_MAC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::setupWindow() {
|
void OverlayWidget::setupWindow() {
|
||||||
_window->setBodyTitleArea([=](QPoint widgetPoint) {
|
_window->setBodyTitleArea([=](QPoint widgetPoint) {
|
||||||
using Flag = Ui::WindowTitleHitTestFlag;
|
using Flag = Ui::WindowTitleHitTestFlag;
|
||||||
if (!_windowed || !_widget->rect().contains(widgetPoint)) {
|
if (!_windowed
|
||||||
|
|| !_widget->rect().contains(widgetPoint)
|
||||||
|
|| _helper->skipTitleHitTest(widgetPoint)) {
|
||||||
return Flag::None | Flag(0);
|
return Flag::None | Flag(0);
|
||||||
}
|
}
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
if (_controls->controls.geometry().contains(widgetPoint)) {
|
|
||||||
return Flag::None | Flag(0);
|
|
||||||
}
|
|
||||||
#endif // !Q_OS_MAC
|
|
||||||
const auto inControls = (_over != OverNone) && (_over != OverVideo);
|
const auto inControls = (_over != OverNone) && (_over != OverVideo);
|
||||||
if (inControls) {
|
if (inControls) {
|
||||||
return Flag::None | Flag(0);
|
return Flag::None | Flag(0);
|
||||||
|
@ -514,7 +507,7 @@ void OverlayWidget::setupWindow() {
|
||||||
|
|
||||||
if (_supportWindowMode) {
|
if (_supportWindowMode) {
|
||||||
const auto callback = [=](Qt::WindowState state) {
|
const auto callback = [=](Qt::WindowState state) {
|
||||||
if (state == Qt::WindowMinimized) {
|
if (state == Qt::WindowMinimized || Platform::IsMac()) {
|
||||||
return;
|
return;
|
||||||
} else if (state == Qt::WindowFullScreen) {
|
} else if (state == Qt::WindowFullScreen) {
|
||||||
_fullscreen = true;
|
_fullscreen = true;
|
||||||
|
@ -1600,7 +1593,15 @@ void OverlayWidget::close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::toggleFullScreen(bool fullscreen) {
|
void OverlayWidget::toggleFullScreen(bool fullscreen) {
|
||||||
if (fullscreen) {
|
if constexpr (Platform::IsMac()) {
|
||||||
|
_fullscreen = fullscreen;
|
||||||
|
_windowed = !fullscreen;
|
||||||
|
_helper->beforeShow(_fullscreen);
|
||||||
|
if (_fullscreen) {
|
||||||
|
moveToScreen();
|
||||||
|
}
|
||||||
|
_helper->afterShow(_fullscreen);
|
||||||
|
} else if (fullscreen) {
|
||||||
_window->showFullScreen();
|
_window->showFullScreen();
|
||||||
} else {
|
} else {
|
||||||
_window->showNormal();
|
_window->showNormal();
|
||||||
|
@ -1697,14 +1698,7 @@ void OverlayWidget::toMessage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::notifyFileDialogShown(bool shown) {
|
void OverlayWidget::notifyFileDialogShown(bool shown) {
|
||||||
if (!_fullscreen || (shown && isHidden())) {
|
_helper->notifyFileDialogShown(shown);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (shown) {
|
|
||||||
Ui::Platform::BringToBack(_window);
|
|
||||||
} else {
|
|
||||||
Ui::Platform::ShowOverAll(_window);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::saveAs() {
|
void OverlayWidget::saveAs() {
|
||||||
|
@ -2871,6 +2865,7 @@ void OverlayWidget::updateThemePreviewGeometry() {
|
||||||
void OverlayWidget::displayFinished() {
|
void OverlayWidget::displayFinished() {
|
||||||
updateControls();
|
updateControls();
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
|
_helper->beforeShow(_fullscreen);
|
||||||
moveToScreen();
|
moveToScreen();
|
||||||
//setAttribute(Qt::WA_DontShowOnScreen);
|
//setAttribute(Qt::WA_DontShowOnScreen);
|
||||||
//OverlayParent::setVisibleHook(true);
|
//OverlayParent::setVisibleHook(true);
|
||||||
|
@ -2887,18 +2882,14 @@ void OverlayWidget::displayFinished() {
|
||||||
|
|
||||||
void OverlayWidget::showAndActivate() {
|
void OverlayWidget::showAndActivate() {
|
||||||
_body->show();
|
_body->show();
|
||||||
if constexpr (Platform::IsMac()) {
|
if (_windowed || Platform::IsMac()) {
|
||||||
_window->show();
|
|
||||||
} else if (_windowed) {
|
|
||||||
_window->showNormal();
|
_window->showNormal();
|
||||||
} else if (_fullscreen) {
|
} else if (_fullscreen) {
|
||||||
_window->showFullScreen();
|
_window->showFullScreen();
|
||||||
} else {
|
} else {
|
||||||
_window->showMaximized();
|
_window->showMaximized();
|
||||||
}
|
}
|
||||||
if (_fullscreen) {
|
_helper->afterShow(_fullscreen);
|
||||||
Ui::Platform::ShowOverAll(_window);
|
|
||||||
}
|
|
||||||
activate();
|
activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4732,7 +4723,8 @@ void OverlayWidget::handleMouseRelease(
|
||||||
} else if (_over == OverMore && _down == OverMore) {
|
} else if (_over == OverMore && _down == OverMore) {
|
||||||
InvokeQueued(_widget, [=] { showDropdown(); });
|
InvokeQueued(_widget, [=] { showDropdown(); });
|
||||||
} else if (_over == OverClose && _down == OverClose) {
|
} else if (_over == OverClose && _down == OverClose) {
|
||||||
close();
|
//close();
|
||||||
|
toggleFullScreen(!_fullscreen);
|
||||||
} else if (_over == OverVideo && _down == OverVideo) {
|
} else if (_over == OverVideo && _down == OverVideo) {
|
||||||
if (_streamed) {
|
if (_streamed) {
|
||||||
playbackPauseResume();
|
playbackPauseResume();
|
||||||
|
|
|
@ -40,9 +40,9 @@ struct ChosenRenderer;
|
||||||
enum class Backend;
|
enum class Backend;
|
||||||
} // namespace Ui::GL
|
} // namespace Ui::GL
|
||||||
|
|
||||||
namespace Ui::Platform {
|
namespace Platform {
|
||||||
struct SeparateTitleControls;
|
class OverlayWidgetHelper;
|
||||||
} // namespace Ui::Platform
|
} // namespace Platform
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
|
@ -455,9 +455,7 @@ private:
|
||||||
bool _opengl = false;
|
bool _opengl = false;
|
||||||
const std::unique_ptr<Ui::GL::Window> _wrap;
|
const std::unique_ptr<Ui::GL::Window> _wrap;
|
||||||
const not_null<Ui::RpWindow*> _window;
|
const not_null<Ui::RpWindow*> _window;
|
||||||
#ifndef Q_OS_MAC
|
const std::unique_ptr<Platform::OverlayWidgetHelper> _helper;
|
||||||
const std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
|
|
||||||
#endif
|
|
||||||
const not_null<Ui::RpWidget*> _body;
|
const not_null<Ui::RpWidget*> _body;
|
||||||
const std::unique_ptr<Ui::RpWidgetWrap> _surface;
|
const std::unique_ptr<Ui::RpWidgetWrap> _surface;
|
||||||
const not_null<QWidget*> _widget;
|
const not_null<QWidget*> _widget;
|
||||||
|
|
20
Telegram/SourceFiles/platform/linux/overlay_widget_linux.h
Normal file
20
Telegram/SourceFiles/platform/linux/overlay_widget_linux.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
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 Platform {
|
||||||
|
|
||||||
|
inline std::unique_ptr<OverlayWidgetHelper> CreateOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize) {
|
||||||
|
return std::make_unique<DefaultOverlayWidgetHelper>(
|
||||||
|
window,
|
||||||
|
std::move(maximize));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Platform
|
37
Telegram/SourceFiles/platform/mac/overlay_widget_mac.h
Normal file
37
Telegram/SourceFiles/platform/mac/overlay_widget_mac.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
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 "platform/platform_overlay_widget.h"
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
|
class MacOverlayWidgetHelper final : public OverlayWidgetHelper {
|
||||||
|
public:
|
||||||
|
MacOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize);
|
||||||
|
~MacOverlayWidgetHelper();
|
||||||
|
|
||||||
|
void beforeShow(bool fullscreen) override;
|
||||||
|
void afterShow(bool fullscreen) override;
|
||||||
|
void notifyFileDialogShown(bool shown) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Data;
|
||||||
|
|
||||||
|
void activate(int button); // NSWindowButton
|
||||||
|
void resolveNative();
|
||||||
|
void updateStyles(bool fullscreen);
|
||||||
|
void refreshButtons(bool fullscreen);
|
||||||
|
|
||||||
|
std::unique_ptr<Data> _data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Platform
|
261
Telegram/SourceFiles/platform/mac/overlay_widget_mac.mm
Normal file
261
Telegram/SourceFiles/platform/mac/overlay_widget_mac.mm
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
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 "platform/mac/overlay_widget_mac.h"
|
||||||
|
|
||||||
|
#include "ui/widgets/rp_window.h"
|
||||||
|
|
||||||
|
#include <QtGui/QWindow>
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface ButtonHandler : NSObject {
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype) initWithCallback:(Fn<void(NSWindowButton)>)callback;
|
||||||
|
- (void) close:(id) sender;
|
||||||
|
- (void) miniaturize:(id) sender;
|
||||||
|
- (void) zoom:(id) sender;
|
||||||
|
|
||||||
|
@end // @interface ButtonHandler
|
||||||
|
|
||||||
|
@implementation ButtonHandler {
|
||||||
|
Fn<void(NSWindowButton)> _callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype) initWithCallback:(Fn<void(NSWindowButton)>)callback {
|
||||||
|
_callback = std::move(callback);
|
||||||
|
return [super init];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) close:(id) sender {
|
||||||
|
_callback(NSWindowCloseButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) miniaturize:(id) sender {
|
||||||
|
_callback(NSWindowMiniaturizeButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) zoom:(id) sender {
|
||||||
|
_callback(NSWindowZoomButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end // @implementation ButtonHandler
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] base::flat_map<int, NSRect> ButtonGeometries() {
|
||||||
|
auto result = base::flat_map<int, NSRect>();
|
||||||
|
auto normal = QWidget();
|
||||||
|
normal.hide();
|
||||||
|
normal.createWinId();
|
||||||
|
const auto view = reinterpret_cast<NSView*>(normal.winId());
|
||||||
|
const auto window = [view window];
|
||||||
|
const auto process = [&](NSWindowButton type) {
|
||||||
|
if (const auto button = [window standardWindowButton:type]) {
|
||||||
|
result.emplace(int(type), [button frame]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
process(NSWindowCloseButton);
|
||||||
|
process(NSWindowMiniaturizeButton);
|
||||||
|
process(NSWindowZoomButton);
|
||||||
|
|
||||||
|
const auto full = [window frame];
|
||||||
|
const auto inner = [window contentRectForFrameRect:full].size.height;
|
||||||
|
const auto height = std::max(full.size.height - inner, 0.);
|
||||||
|
|
||||||
|
result[int(NSWindowToolbarButton)] = { CGPoint(), CGSize{ full.size.width, height }};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
struct MacOverlayWidgetHelper::Data {
|
||||||
|
const not_null<Ui::RpWindow*> window;
|
||||||
|
const Fn<void(bool)> maximize;
|
||||||
|
const base::flat_map<int, NSRect> buttons;
|
||||||
|
ButtonHandler *handler = nil;
|
||||||
|
NSWindow * __weak native = nil;
|
||||||
|
NSButton * __weak closeNative = nil;
|
||||||
|
NSButton * __weak miniaturizeNative = nil;
|
||||||
|
NSButton * __weak zoomNative = nil;
|
||||||
|
NSButton * __weak close = nil;
|
||||||
|
NSButton * __weak miniaturize = nil;
|
||||||
|
NSButton * __weak zoom = nil;
|
||||||
|
};
|
||||||
|
|
||||||
|
MacOverlayWidgetHelper::MacOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize)
|
||||||
|
: _data(std::make_unique<Data>(Data{
|
||||||
|
.window = window,
|
||||||
|
.maximize = std::move(maximize),
|
||||||
|
.buttons = ButtonGeometries(),
|
||||||
|
.handler = [[ButtonHandler alloc] initWithCallback:[=](NSWindowButton button) {
|
||||||
|
activate(int(button));
|
||||||
|
}]
|
||||||
|
})) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MacOverlayWidgetHelper::~MacOverlayWidgetHelper() {
|
||||||
|
[_data->handler release];
|
||||||
|
_data->handler = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::activate(int button) {
|
||||||
|
const auto fullscreen = (_data->window->windowHandle()->flags() & Qt::FramelessWindowHint);
|
||||||
|
switch (NSWindowButton(button)) {
|
||||||
|
case NSWindowCloseButton: _data->window->close(); return;
|
||||||
|
case NSWindowMiniaturizeButton: [_data->native miniaturize:_data->handler]; return;
|
||||||
|
case NSWindowZoomButton: _data->maximize(!fullscreen); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::beforeShow(bool fullscreen) {
|
||||||
|
_data->window->setAttribute(Qt::WA_MacAlwaysShowToolWindow, !fullscreen);
|
||||||
|
_data->window->windowHandle()->setFlag(Qt::FramelessWindowHint, fullscreen);
|
||||||
|
if (!fullscreen) {
|
||||||
|
_data->window->setGeometry({ 100, 100, 800, 600 });
|
||||||
|
}
|
||||||
|
updateStyles(fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::afterShow(bool fullscreen) {
|
||||||
|
updateStyles(fullscreen);
|
||||||
|
refreshButtons(fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::resolveNative() {
|
||||||
|
if (const auto handle = _data->window->winId()) {
|
||||||
|
_data->native = [reinterpret_cast<NSView*>(handle) window];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::updateStyles(bool fullscreen) {
|
||||||
|
resolveNative();
|
||||||
|
if (!_data->native) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto window = _data->native;
|
||||||
|
const auto level = !fullscreen
|
||||||
|
? NSNormalWindowLevel
|
||||||
|
: NSPopUpMenuWindowLevel;
|
||||||
|
[window setLevel:level];
|
||||||
|
[window setHidesOnDeactivate:!_data->window->testAttribute(Qt::WA_MacAlwaysShowToolWindow)];
|
||||||
|
[window setTitleVisibility:NSWindowTitleHidden];
|
||||||
|
[window setTitlebarAppearsTransparent:YES];
|
||||||
|
[window setStyleMask:[window styleMask] | NSWindowStyleMaskFullSizeContentView];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::refreshButtons(bool fullscreen) {
|
||||||
|
Expects(_data->native != nullptr);
|
||||||
|
|
||||||
|
const auto window = _data->native;
|
||||||
|
auto next = CGPoint();
|
||||||
|
const auto added = [&](NSRect frame) {
|
||||||
|
const auto left = frame.origin.x + frame.size.width * 1.5;
|
||||||
|
const auto top = frame.origin.y;
|
||||||
|
if (next.x < left) {
|
||||||
|
next.x = left;
|
||||||
|
}
|
||||||
|
next.y = top;
|
||||||
|
};
|
||||||
|
for (const auto &[type, frame] : _data->buttons) {
|
||||||
|
added(frame);
|
||||||
|
}
|
||||||
|
const auto skip = fullscreen
|
||||||
|
? _data->buttons.find(int(NSWindowToolbarButton))->second.size.height
|
||||||
|
: 0.;
|
||||||
|
const auto process = [&](auto native, auto custom, NSWindowButton type, auto action) {
|
||||||
|
auto retained = (NSButton*)nil;
|
||||||
|
while (const auto button = [window standardWindowButton:type]) {
|
||||||
|
if ([button superview] != [window contentView]) {
|
||||||
|
*native = button;
|
||||||
|
[button setHidden:YES];
|
||||||
|
break;
|
||||||
|
} else if (button == *custom) {
|
||||||
|
retained = [button retain];
|
||||||
|
}
|
||||||
|
[button removeFromSuperview];
|
||||||
|
}
|
||||||
|
const auto i = _data->buttons.find(int(type));
|
||||||
|
const auto frame = [&](NSButton *button) {
|
||||||
|
if (i != end(_data->buttons)) {
|
||||||
|
auto origin = i->second.origin;
|
||||||
|
origin.y += skip;
|
||||||
|
return NSRect{ origin, i->second.size };
|
||||||
|
}
|
||||||
|
const auto size = [button frame].size;
|
||||||
|
auto result = NSRect{ next, size };
|
||||||
|
added(result);
|
||||||
|
result.origin.y += skip;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
if (!retained) {
|
||||||
|
if (*custom) {
|
||||||
|
retained = *custom;
|
||||||
|
[retained retain];
|
||||||
|
[retained removeFromSuperview];
|
||||||
|
} else {
|
||||||
|
const auto style = NSWindowStyleMaskTitled
|
||||||
|
| NSWindowStyleMaskClosable
|
||||||
|
| NSWindowStyleMaskMiniaturizable
|
||||||
|
| NSWindowStyleMaskResizable;
|
||||||
|
*custom
|
||||||
|
= retained
|
||||||
|
= [NSWindow standardWindowButton:type forStyleMask:style];
|
||||||
|
[retained setTarget:_data->handler];
|
||||||
|
[retained setAction:action];
|
||||||
|
[retained retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[[window contentView] addSubview:retained];
|
||||||
|
[retained setFrame:frame(retained)];
|
||||||
|
[retained setEnabled:YES];
|
||||||
|
[retained setHidden:NO];
|
||||||
|
[retained release];
|
||||||
|
};
|
||||||
|
process(
|
||||||
|
&_data->closeNative,
|
||||||
|
&_data->close,
|
||||||
|
NSWindowCloseButton,
|
||||||
|
@selector(close:));
|
||||||
|
process(
|
||||||
|
&_data->miniaturizeNative,
|
||||||
|
&_data->miniaturize,
|
||||||
|
NSWindowMiniaturizeButton,
|
||||||
|
@selector(miniaturize:));
|
||||||
|
process(
|
||||||
|
&_data->zoomNative,
|
||||||
|
&_data->zoom,
|
||||||
|
NSWindowZoomButton,
|
||||||
|
@selector(zoom:));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOverlayWidgetHelper::notifyFileDialogShown(bool shown) {
|
||||||
|
resolveNative();
|
||||||
|
if (_data->native && !_data->window->isHidden()) {
|
||||||
|
const auto level = [_data->native level];
|
||||||
|
if (level != NSNormalWindowLevel) {
|
||||||
|
const auto level = shown
|
||||||
|
? NSModalPanelWindowLevel
|
||||||
|
: NSPopUpMenuWindowLevel;
|
||||||
|
[_data->native setLevel:level];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<OverlayWidgetHelper> CreateOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize) {
|
||||||
|
return std::make_unique<MacOverlayWidgetHelper>(
|
||||||
|
window,
|
||||||
|
std::move(maximize));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Platform
|
34
Telegram/SourceFiles/platform/platform_overlay_widget.cpp
Normal file
34
Telegram/SourceFiles/platform/platform_overlay_widget.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
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 "platform/platform_overlay_widget.h"
|
||||||
|
|
||||||
|
#include "ui/platform/ui_platform_window_title.h"
|
||||||
|
#include "styles/style_calls.h"
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
|
DefaultOverlayWidgetHelper::DefaultOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize)
|
||||||
|
: _controls(Ui::Platform::SetupSeparateTitleControls(
|
||||||
|
window,
|
||||||
|
st::callTitle,
|
||||||
|
std::move(maximize))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultOverlayWidgetHelper::~DefaultOverlayWidgetHelper() = default;
|
||||||
|
|
||||||
|
void DefaultOverlayWidgetHelper::orderWidgets() {
|
||||||
|
_controls->wrap.raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DefaultOverlayWidgetHelper::skipTitleHitTest(QPoint position) {
|
||||||
|
return _controls->controls.geometry().contains(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Platform
|
66
Telegram/SourceFiles/platform/platform_overlay_widget.h
Normal file
66
Telegram/SourceFiles/platform/platform_overlay_widget.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
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 Ui {
|
||||||
|
class RpWindow;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Ui::Platform {
|
||||||
|
struct SeparateTitleControls;
|
||||||
|
} // namespace Ui::Platform
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
|
class OverlayWidgetHelper {
|
||||||
|
public:
|
||||||
|
virtual ~OverlayWidgetHelper() = default;
|
||||||
|
|
||||||
|
virtual void orderWidgets() {
|
||||||
|
}
|
||||||
|
[[nodiscard]] virtual bool skipTitleHitTest(QPoint position) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual void beforeShow(bool fullscreen) {
|
||||||
|
}
|
||||||
|
virtual void afterShow(bool fullscreen) {
|
||||||
|
}
|
||||||
|
virtual void notifyFileDialogShown(bool shown) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<OverlayWidgetHelper> CreateOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize);
|
||||||
|
|
||||||
|
class DefaultOverlayWidgetHelper final : public OverlayWidgetHelper {
|
||||||
|
public:
|
||||||
|
DefaultOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize);
|
||||||
|
~DefaultOverlayWidgetHelper();
|
||||||
|
|
||||||
|
void orderWidgets() override;
|
||||||
|
bool skipTitleHitTest(QPoint position) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Platform
|
||||||
|
|
||||||
|
// Platform dependent implementations.
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
#include "platform/mac/overlay_widget_mac.h"
|
||||||
|
#elif defined Q_OS_UNIX // Q_OS_MAC
|
||||||
|
#include "platform/linux/overlay_widget_linux.h"
|
||||||
|
#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX
|
||||||
|
#include "platform/win/overlay_widget_win.h"
|
||||||
|
#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WIN
|
20
Telegram/SourceFiles/platform/win/overlay_widget_win.h
Normal file
20
Telegram/SourceFiles/platform/win/overlay_widget_win.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
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 Platform {
|
||||||
|
|
||||||
|
inline std::unique_ptr<OverlayWidgetHelper> CreateOverlayWidgetHelper(
|
||||||
|
not_null<Ui::RpWindow*> window,
|
||||||
|
Fn<void(bool)> maximize) {
|
||||||
|
return std::make_unique<DefaultOverlayWidgetHelper>(
|
||||||
|
window,
|
||||||
|
std::move(maximize));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Platform
|
|
@ -404,7 +404,7 @@ if customRunCommand:
|
||||||
stage('patches', """
|
stage('patches', """
|
||||||
git clone https://github.com/desktop-app/patches.git
|
git clone https://github.com/desktop-app/patches.git
|
||||||
cd patches
|
cd patches
|
||||||
git checkout 720e1863f0
|
git checkout d0fc458228
|
||||||
""")
|
""")
|
||||||
|
|
||||||
stage('msys64', """
|
stage('msys64', """
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a56831e8d00c58108a6b4ea6caf1c4e9cfe7f838
|
Subproject commit c4838f589905fde2d43e3c3d37700523acf2ab9d
|
Loading…
Add table
Reference in a new issue