Files
obs-studio/UI/window-projector.cpp
SuslikV 7eee8de331 UI: Do not quit program when last windows are projectors
Prevents the program from unintentionally quitting if the program is
minimized to the task tray and the user closes all projectors

Closes jp9000/obs-studio#737
2017-01-25 20:23:03 -08:00

137 lines
3.3 KiB
C++

#include <QAction>
#include <QGuiApplication>
#include <QMouseEvent>
#include <QMenu>
#include <QScreen>
#include "window-projector.hpp"
#include "display-helpers.hpp"
#include "qt-wrappers.hpp"
#include "platform.hpp"
#include "obs-app.hpp"
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_)
: OBSQTDisplay (widget,
Qt::Window | Qt::FramelessWindowHint |
Qt::X11BypassWindowManagerHint),
source (source_),
removedSignal (obs_source_get_signal_handler(source),
"remove", OBSSourceRemoved, this)
{
setAttribute(Qt::WA_DeleteOnClose, true);
//disable application quit when last window closed
setAttribute(Qt::WA_QuitOnClose, false);
installEventFilter(CreateShortcutFilter());
auto addDrawCallback = [this] ()
{
obs_display_add_draw_callback(GetDisplay(), OBSRender, this);
obs_display_set_background_color(GetDisplay(), 0x000000);
};
connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);
bool hideCursor = config_get_bool(GetGlobalConfig(),
"BasicWindow", "HideProjectorCursor");
if (hideCursor) {
QPixmap empty(16, 16);
empty.fill(Qt::transparent);
setCursor(QCursor(empty));
}
App()->IncrementSleepInhibition();
}
OBSProjector::~OBSProjector()
{
if (source)
obs_source_dec_showing(source);
App()->DecrementSleepInhibition();
}
void OBSProjector::Init(int monitor)
{
QScreen *screen = QGuiApplication::screens()[monitor];
setGeometry(screen->geometry());
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ProjectorAlwaysOnTop");
if (alwaysOnTop)
SetAlwaysOnTop(this, true);
show();
if (source)
obs_source_inc_showing(source);
QAction *action = new QAction(this);
action->setShortcut(Qt::Key_Escape);
addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
}
void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
{
OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
uint32_t targetCX;
uint32_t targetCY;
int x, y;
int newCX, newCY;
float scale;
if (window->source) {
targetCX = std::max(obs_source_get_width(window->source), 1u);
targetCY = std::max(obs_source_get_height(window->source), 1u);
} else {
struct obs_video_info ovi;
obs_get_video_info(&ovi);
targetCX = ovi.base_width;
targetCY = ovi.base_height;
}
GetScaleAndCenterPos(targetCX, targetCY, cx, cy, x, y, scale);
newCX = int(scale * float(targetCX));
newCY = int(scale * float(targetCY));
gs_viewport_push();
gs_projection_push();
gs_ortho(0.0f, float(targetCX), 0.0f, float(targetCY), -100.0f, 100.0f);
gs_set_viewport(x, y, newCX, newCY);
if (window->source)
obs_source_video_render(window->source);
else
obs_render_main_view();
gs_projection_pop();
gs_viewport_pop();
}
void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params)
{
OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
window->deleteLater();
UNUSED_PARAMETER(params);
}
void OBSProjector::mousePressEvent(QMouseEvent *event)
{
OBSQTDisplay::mousePressEvent(event);
if (event->button() == Qt::RightButton) {
QMenu popup(this);
popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
popup.exec(QCursor::pos());
}
}
void OBSProjector::EscapeTriggered()
{
deleteLater();
}