Skip to content

Commit

Permalink
UI: Make window-projector its own top level QWidget
Browse files Browse the repository at this point in the history
Previously OBSProjector was a subclass of OBSQTDisplay, which is
intended to own the entire surface it draws on. On wayland some
compositors expect the client to draw decorations (window titlebar), but
because OBSQTDisplay draws on the entire surface directly the client
decorations from QT are overwritten.

Instead promote OBSProjector to a simple QWidget with a single layout
containing the OBSQTDisplay. This allows the OBSQTDisplay to own the
entire contents while OBSProjector draws the decorations.

fixes obsproject#6283
  • Loading branch information
kkartaltepe committed Apr 20, 2022
1 parent 4c96fea commit 3379a8f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
4 changes: 4 additions & 0 deletions UI/qt-display.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

#define GREY_COLOR_BACKGROUND 0xFF4C4C4C

class OBSProjector;

class OBSQTDisplay : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor READ
GetDisplayBackgroundColor WRITE
SetDisplayBackgroundColor)

friend class OBSProjector;

OBSDisplay display;

virtual void paintEvent(QPaintEvent *event) override;
Expand Down
25 changes: 16 additions & 9 deletions UI/window-projector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ static size_t maxSrcs, numSrcs;

OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
ProjectorType type_)
: OBSQTDisplay(widget, Qt::Window),
: display(this),
source(source_),
removedSignal(obs_source_get_signal_handler(source), "remove",
OBSSourceRemoved, this)
{
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(&display);
layout->setContentsMargins(0, 0, 0, 0);
this->setLayout(layout);

isAlwaysOnTop = config_get_bool(GetGlobalConfig(), "BasicWindow",
"ProjectorAlwaysOnTop");

Expand All @@ -32,7 +37,7 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,

// Mark the window as a projector so SetDisplayAffinity
// can skip it
windowHandle()->setProperty("isOBSProjectorWindow", true);
display.windowHandle()->setProperty("isOBSProjectorWindow", true);

#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
// Prevents resizing of projector windows
Expand Down Expand Up @@ -69,12 +74,14 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
auto addDrawCallback = [this]() {
bool isMultiview = type == ProjectorType::Multiview;
obs_display_add_draw_callback(
GetDisplay(),
display.GetDisplay(),
isMultiview ? OBSRenderMultiview : OBSRender, this);
obs_display_set_background_color(GetDisplay(), 0x000000);
obs_display_set_background_color(display.GetDisplay(),
0x000000);
};

connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);
display.connect(&display, &OBSQTDisplay::DisplayCreated,
addDrawCallback);
connect(App(), &QGuiApplication::screenRemoved, this,
&OBSProjector::ScreenRemoved);

Expand Down Expand Up @@ -106,8 +113,8 @@ OBSProjector::~OBSProjector()
{
bool isMultiview = type == ProjectorType::Multiview;
obs_display_remove_draw_callback(
GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender,
this);
display.GetDisplay(),
isMultiview ? OBSRenderMultiview : OBSRender, this);

if (source)
obs_source_dec_showing(source);
Expand Down Expand Up @@ -874,7 +881,7 @@ static int getSourceByPosition(int x, int y, float ratio)

void OBSProjector::mouseDoubleClickEvent(QMouseEvent *event)
{
OBSQTDisplay::mouseDoubleClickEvent(event);
display.mouseDoubleClickEvent(event);

if (!mouseSwitching)
return;
Expand All @@ -901,7 +908,7 @@ void OBSProjector::mouseDoubleClickEvent(QMouseEvent *event)

void OBSProjector::mousePressEvent(QMouseEvent *event)
{
OBSQTDisplay::mousePressEvent(event);
display.mousePressEvent(event);

if (event->button() == Qt::RightButton) {
OBSBasic *main =
Expand Down
3 changes: 2 additions & 1 deletion UI/window-projector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ enum class MultiviewLayout : uint8_t {
SCENES_ONLY_25_SCENES = 9,
};

class OBSProjector : public OBSQTDisplay {
class OBSProjector : public QWidget {
Q_OBJECT

private:
OBSSource source;
OBSSignal removedSignal;
OBSQTDisplay display;

static void OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy);
static void OBSRender(void *data, uint32_t cx, uint32_t cy);
Expand Down

0 comments on commit 3379a8f

Please sign in to comment.