test_main.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/basic_types.h"
  9. #include "base/integration.h"
  10. #include "ui/style/style_core_scale.h"
  11. #include "ui/integration.h"
  12. #include <crl/crl.h>
  13. #include <rpl/rpl.h>
  14. #include <QApplication>
  15. #include <QAbstractNativeEventFilter>
  16. #include <QThread>
  17. #include <QDir>
  18. namespace Ui {
  19. class RpWidget;
  20. class RpWindow;
  21. } // namespace Ui
  22. namespace Test {
  23. [[nodiscard]] QString name();
  24. void test(not_null<Ui::RpWindow*> window, not_null<Ui::RpWidget*> widget);
  25. [[nodiscard]] inline int scale(int value) {
  26. return style::ConvertScale(value);
  27. };
  28. class App final : public QApplication, public QAbstractNativeEventFilter {
  29. public:
  30. using QApplication::QApplication;
  31. template <typename Callable>
  32. auto customEnterFromEventLoop(Callable &&callable) {
  33. registerEnterFromEventLoop();
  34. const auto wrap = createEventNestingLevel();
  35. return callable();
  36. }
  37. void postponeCall(FnMut<void()> &&callable);
  38. [[nodiscard]] rpl::producer<> widgetUpdateRequests() const;
  39. private:
  40. struct PostponedCall {
  41. int loopNestingLevel = 0;
  42. FnMut<void()> callable;
  43. };
  44. auto createEventNestingLevel() {
  45. incrementEventNestingLevel();
  46. return gsl::finally([=] { decrementEventNestingLevel(); });
  47. }
  48. void checkForEmptyLoopNestingLevel();
  49. void processPostponedCalls(int level);
  50. void incrementEventNestingLevel();
  51. void decrementEventNestingLevel();
  52. void registerEnterFromEventLoop();
  53. bool notifyOrInvoke(QObject *receiver, QEvent *e);
  54. bool notify(QObject *receiver, QEvent *e) override;
  55. bool nativeEventFilter(
  56. const QByteArray &eventType,
  57. void *message,
  58. native_event_filter_result *result) override;
  59. rpl::event_stream<> _widgetUpdateRequests;
  60. Qt::HANDLE _mainThreadId = QThread::currentThreadId();
  61. int _eventNestingLevel = 0;
  62. int _loopNestingLevel = 0;
  63. std::vector<int> _previousLoopNestingLevels;
  64. std::vector<PostponedCall> _postponedCalls;
  65. };
  66. [[nodiscard]] inline App &app() {
  67. return *static_cast<App*>(QCoreApplication::instance());
  68. }
  69. class BaseIntegration final : public base::Integration {
  70. public:
  71. using Integration::Integration;
  72. void enterFromEventLoop(FnMut<void()> &&method);
  73. bool logSkipDebug();
  74. void logMessageDebug(const QString &message);
  75. void logMessage(const QString &message);
  76. };
  77. class UiIntegration final : public Ui::Integration {
  78. public:
  79. void postponeCall(FnMut<void()> &&callable);
  80. void registerLeaveSubscription(not_null<QWidget*> widget);
  81. void unregisterLeaveSubscription(not_null<QWidget*> widget);
  82. QString emojiCacheFolder();
  83. QString openglCheckFilePath();
  84. QString angleBackendFilePath();
  85. };
  86. } // namespace Test