UI: Fix potential race condition for hover items
The graphics thread should not be accessing any Qt objects that aren't guaranteed to exist. Instead, store the currently hovering list/preview scene items in the preview class.
This commit is contained in:
parent
7068e61fd9
commit
1b8ecae3b9
@ -1270,14 +1270,21 @@ void SourceTree::dropEvent(QDropEvent *event)
|
||||
void SourceTree::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint pos = event->pos();
|
||||
SourceTreeItem *item = qobject_cast<SourceTreeItem *>
|
||||
(childAt(pos));
|
||||
SourceTreeItem *item = qobject_cast<SourceTreeItem *>(childAt(pos));
|
||||
|
||||
currentHover = item;
|
||||
OBSBasicPreview *preview = OBSBasicPreview::Get();
|
||||
preview->hoveredListItem = !!item ? item->sceneitem : nullptr;
|
||||
|
||||
QListView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void SourceTree::leaveEvent(QEvent *event)
|
||||
{
|
||||
OBSBasicPreview *preview = OBSBasicPreview::Get();
|
||||
preview->hoveredListItem = nullptr;
|
||||
QListView::leaveEvent(event);
|
||||
}
|
||||
|
||||
void SourceTree::selectionChanged(
|
||||
const QItemSelection &selected,
|
||||
const QItemSelection &deselected)
|
||||
|
@ -142,8 +142,6 @@ class SourceTree : public QListView {
|
||||
return reinterpret_cast<SourceTreeModel *>(model());
|
||||
}
|
||||
|
||||
SourceTreeItem *currentHover;
|
||||
|
||||
public:
|
||||
inline SourceTreeItem *GetItemWidget(int idx)
|
||||
{
|
||||
@ -151,14 +149,6 @@ public:
|
||||
return reinterpret_cast<SourceTreeItem *>(widget);
|
||||
}
|
||||
|
||||
inline SourceTreeItem *GetHoveredItem()
|
||||
{
|
||||
if (underMouse()) {
|
||||
return currentHover;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
explicit SourceTree(QWidget *parent = nullptr);
|
||||
|
||||
inline bool IgnoreReorder() const {return ignoreReorder;}
|
||||
@ -186,6 +176,7 @@ protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
virtual void dropEvent(QDropEvent *event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
virtual void leaveEvent(QEvent *event) override;
|
||||
|
||||
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
|
||||
};
|
||||
|
@ -616,7 +616,7 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
|
||||
cropping = false;
|
||||
|
||||
OBSSceneItem item = GetItemAtPos(pos, true);
|
||||
hovered = item;
|
||||
hoveredPreviewItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1163,7 +1163,7 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
|
||||
return;
|
||||
|
||||
if (mouseDown) {
|
||||
hovered = nullptr;
|
||||
hoveredPreviewItem = nullptr;
|
||||
|
||||
vec2 pos = GetMouseEventPos(event);
|
||||
|
||||
@ -1205,13 +1205,13 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
|
||||
vec2 pos = GetMouseEventPos(event);
|
||||
OBSSceneItem item = GetItemAtPos(pos, true);
|
||||
|
||||
hovered = item;
|
||||
hoveredPreviewItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasicPreview::leaveEvent(QEvent *event)
|
||||
{
|
||||
hovered = nullptr;
|
||||
hoveredPreviewItem = nullptr;
|
||||
|
||||
UNUSED_PARAMETER(event);
|
||||
}
|
||||
@ -1408,16 +1408,14 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
|
||||
SourceTreeItem *hovItem = main->ui->sources->GetHoveredItem();
|
||||
SourceTreeItem *curItem = main->GetItemWidgetFromSceneItem(item);
|
||||
|
||||
bool hover = (curItem && hovItem == curItem) || prev->hovered == item;
|
||||
bool hovered = prev->hoveredPreviewItem == item ||
|
||||
prev->hoveredListItem == item;
|
||||
bool selected = obs_sceneitem_selected(item);
|
||||
|
||||
if (!selected && !hover)
|
||||
if (!selected && !hovered)
|
||||
return true;
|
||||
|
||||
matrix4 boxTransform;
|
||||
@ -1466,7 +1464,7 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
||||
|
||||
if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) {
|
||||
#define DRAW_SIDE(side, x1, y1, x2, y2) \
|
||||
if (hover && !selected) \
|
||||
if (hovered && !selected) \
|
||||
gs_effect_set_vec4(colParam, &blue); \
|
||||
else if (crop.side > 0) \
|
||||
gs_effect_set_vec4(colParam, &green); \
|
||||
|
@ -31,6 +31,8 @@ enum class ItemHandle : uint32_t {
|
||||
class OBSBasicPreview : public OBSQTDisplay {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SourceTree;
|
||||
|
||||
private:
|
||||
obs_sceneitem_crop startCrop;
|
||||
vec2 startItemPos;
|
||||
@ -56,10 +58,12 @@ private:
|
||||
bool locked = false;
|
||||
bool scrollMode = false;
|
||||
bool fixedScaling = false;
|
||||
OBSSceneItem hovered = nullptr;
|
||||
int32_t scalingLevel = 0;
|
||||
float scalingAmount = 1.0f;
|
||||
|
||||
obs_sceneitem_t *hoveredPreviewItem = nullptr;
|
||||
obs_sceneitem_t *hoveredListItem = nullptr;
|
||||
|
||||
static vec2 GetMouseEventPos(QMouseEvent *event);
|
||||
static bool DrawSelectedOverflow(obs_scene_t *scene,
|
||||
obs_sceneitem_t *item, void *param);
|
||||
|
Loading…
x
Reference in New Issue
Block a user