diff options
| -rw-r--r-- | compat/check-visible.cpp | 67 | ||||
| -rw-r--r-- | compat/check-visible.hpp | 9 | ||||
| -rw-r--r-- | cv/video-widget.cpp | 5 | ||||
| -rw-r--r-- | gui/main-window.cpp | 29 | ||||
| -rw-r--r-- | gui/main-window.hpp | 1 | ||||
| -rw-r--r-- | pose-widget/pose-widget.cpp | 4 | 
6 files changed, 115 insertions, 0 deletions
| diff --git a/compat/check-visible.cpp b/compat/check-visible.cpp new file mode 100644 index 00000000..6030ad92 --- /dev/null +++ b/compat/check-visible.cpp @@ -0,0 +1,67 @@ +#include "check-visible.hpp" + +#if defined _WIN32 + +#include "timer.hpp" + +#include <QMutexLocker> + +#include <windows.h> + +static constexpr int visible_timeout = 5000; + +static Timer timer; +static QMutex mtx; +static bool visible = true; + +never_inline OTR_COMPAT_EXPORT +void set_is_visible(const QWidget& w, bool force) +{ +    QMutexLocker l(&mtx); + +    if (!force && timer.elapsed_ms() < visible_timeout) +        return; + +    timer.start(); + +    const HWND id = (HWND) w.winId(); +    const QPoint pt = w.mapToGlobal({ 0, 0 }); + +    const int W = w.width(), H = w.height(); + +    const QPoint points[] = +    { +        pt, +        pt + QPoint(W - 1, 0), +        pt + QPoint(0, H - 1), +        pt + QPoint(W - 1, H - 1), +        pt + QPoint(W / 2, H / 2), +    }; + +    for (const QPoint& pt : points) +        if (!!(visible = WindowFromPoint({ pt.x(), pt.y() }) == id)) +            break; +} + +never_inline OTR_COMPAT_EXPORT +bool check_is_visible() +{ +    QMutexLocker l(&mtx); + +    return visible; +} + +#else + +always_inline OTR_COMPAT_EXPORT +void set_is_visible(const QWidget&) +{ +} + +always_inline OTR_COMPAT_EXPORT +bool check_is_visible() +{ +    return true; +} + +#endif diff --git a/compat/check-visible.hpp b/compat/check-visible.hpp new file mode 100644 index 00000000..f5420a39 --- /dev/null +++ b/compat/check-visible.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "export.hpp" +#include "util.hpp" + +#include <QWidget> + +never_inline OTR_COMPAT_EXPORT void set_is_visible(QWidget const& w, bool force = false); +never_inline OTR_COMPAT_EXPORT bool check_is_visible(); diff --git a/cv/video-widget.cpp b/cv/video-widget.cpp index 7d504f3a..bad81905 100644 --- a/cv/video-widget.cpp +++ b/cv/video-widget.cpp @@ -7,6 +7,8 @@   */  #include "video-widget.hpp" +#include "compat/check-visible.hpp" +  #include <opencv2/imgproc.hpp>  cv_video_widget::cv_video_widget(QWidget* parent) : QWidget(parent), @@ -67,6 +69,9 @@ void cv_video_widget::paintEvent(QPaintEvent*)  void cv_video_widget::update_and_repaint()  { +    if (!check_is_visible()) +        return; +      QMutexLocker l(&mtx);      preview_size = size(); diff --git a/gui/main-window.cpp b/gui/main-window.cpp index 225d0629..49de59d1 100644 --- a/gui/main-window.cpp +++ b/gui/main-window.cpp @@ -12,6 +12,8 @@  #include "opentrack-library-path.h"  #include "new_file_dialog.h"  #include "migration/migration.hpp" +#include "compat/check-visible.hpp" +  #include <QFile>  #include <QFileDialog>  #include <QDesktopServices> @@ -561,6 +563,11 @@ void MainWindow::set_title(const QString& game_title_)  void MainWindow::showHeadPose()  { +    set_is_visible(*this); + +    if (!check_is_visible()) +        return; +      double mapped[6], raw[6];      work->tracker->raw_and_mapped_pose(mapped, raw); @@ -840,6 +847,28 @@ void MainWindow::closeEvent(QCloseEvent*)      exit();  } +bool MainWindow::event(QEvent* event) +{ +    using t = QEvent::Type; + +    if (work) +    { +        switch (event->type()) +        { +        case t::Show: +        case t::Hide: +        case t::WindowActivate: +        case t::WindowDeactivate: +        case t::WindowStateChange: +            set_is_visible(*this, true); +            /*FALLTHROUGH*/ +        default: +            break; +        } +    } +    return QMainWindow::event(event); +} +  bool MainWindow::is_tray_enabled()  {      return s.tray_enabled && QSystemTrayIcon::isSystemTrayAvailable(); diff --git a/gui/main-window.hpp b/gui/main-window.hpp index d49be9c1..02e65d4c 100644 --- a/gui/main-window.hpp +++ b/gui/main-window.hpp @@ -95,6 +95,7 @@ class MainWindow : public QMainWindow, private State      void changeEvent(QEvent* e) override;      void closeEvent(QCloseEvent*) override; +    bool event(QEvent *event) override;      bool maybe_hide_to_tray(QEvent* e);      // only use in impl file since no definition in header! diff --git a/pose-widget/pose-widget.cpp b/pose-widget/pose-widget.cpp index 65f4c1e8..f2976a5d 100644 --- a/pose-widget/pose-widget.cpp +++ b/pose-widget/pose-widget.cpp @@ -9,6 +9,7 @@  #include "compat/util.hpp"  #include "compat/timer.hpp"  #include "compat/sleep.hpp" +#include "compat/check-visible.hpp"  #include <cmath>  #include <algorithm>  #include <QPainter> @@ -86,6 +87,9 @@ pose_widget::~pose_widget()  void pose_widget::rotate_async(double xAngle, double yAngle, double zAngle, double x, double y, double z)  { +    if (!check_is_visible()) +        return; +      bool expected = true;      if (xform.fresh.compare_exchange_weak(expected, false))      { | 
