Skip to content

Commit 6e526c6

Browse files
dcwhiteclaude
andcommitted
Fix widget selection on high-DPI displays; remove 'hack' shader toggle
The widget-selection render pass drew into an FBO sized in Qt logical (widget) coordinates but inherited whatever viewport was last set. Qt sets the viewport to the physical framebuffer size (logical size times devicePixelRatio) before each paintGL, so on high-DPI displays the selection scene was rendered at devicePixelRatio scale relative to the FBO and mouse coordinates, breaking shift-click widget picking. The 'Viewer widget selection correction' preference compensated by scaling NDC by 0.5 in the selection vertex shader (a uniform literally named "hack"), which only worked for devicePixelRatio == 2 (e.g. Retina Macs). It was wrong for standard displays (hence the toggle) and for fractional scale factors (e.g. 125%/150% on Windows, common with Qt 6), where neither setting worked. Fix the root cause instead: explicitly set the viewport to the selection FBO's size while rendering the selection pass, so clip space maps onto the FBO 1:1 regardless of display scale, and restore the previous viewport afterward. Remove the hack uniform, the widgetSelectionCorrection preference, its settings entry, and the preferences-dialog checkbox. Fixes #2558 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent dcbe7d9 commit 6e526c6

7 files changed

Lines changed: 10 additions & 29 deletions

File tree

src/Core/Application/Preferences/Preferences.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ Preferences::Preferences() :
5151
highlightPorts("highlightPorts", false),
5252
autoNotes("autoNotes", false),
5353
highDPIAdjustment("highDPIAdjustment", false),
54-
widgetSelectionCorrection("widgetSelectionCorrection", false),
5554
autoRotateViewerOnMouseRelease("autoRotateViewerOnMouseRelease", false),
5655
moduleExecuteDownstreamOnly("moduleExecuteDownstreamOnly", true),
5756
forceGridBackground("forceGridBackground", false),

src/Core/Application/Preferences/Preferences.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ namespace SCIRun
8686
BooleanVariable highlightPorts;
8787
BooleanVariable autoNotes;
8888
BooleanVariable highDPIAdjustment;
89-
BooleanVariable widgetSelectionCorrection;
9089
BooleanVariable autoRotateViewerOnMouseRelease;
9190
TrackedVariable<BooleanVariable> moduleExecuteDownstreamOnly;
9291
TrackedVariable<BooleanVariable> forceGridBackground;

src/Interface/Application/Preferences.ui

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,6 @@
412412
</widget>
413413
</item>
414414
<item row="1" column="0">
415-
<widget class="QCheckBox" name="viewerWidgetSelectionCorrectionCheckbox_">
416-
<property name="text">
417-
<string>Viewer widget selection correction--enable if widgets don't respond to shift-click actions</string>
418-
</property>
419-
</widget>
420-
</item>
421-
<item row="2" column="0">
422415
<widget class="QGroupBox" name="groupBox_2">
423416
<property name="minimumSize">
424417
<size>

src/Interface/Application/PreferencesWindow.cc

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,12 @@ PreferencesWindow::PreferencesWindow(NetworkEditor* editor, std::function<void()
4646
connect(errorGraphicItemsCheckBox_, &QCheckBox::stateChanged, this, &PreferencesWindow::updateModuleErrorInlineMessagesOption);
4747
connect(highDPIAdjustCheckBox_, &QCheckBox::stateChanged, this, &PreferencesWindow::updateHighDPIAdjust);
4848
connect(forceGridBackgroundCheckBox_, &QCheckBox::stateChanged, this, &PreferencesWindow::updateForceGridBackground);
49-
connect(viewerWidgetSelectionCorrectionCheckbox_, &QCheckBox::stateChanged, this, &PreferencesWindow::updateWidgetSelectionCorrection);
5049
connect(autoRotateViewerOnMouseReleaseCheckbox_, &QCheckBox::stateChanged, this, &PreferencesWindow::updateAutoRotateViewer);
5150
connect(moduleExecuteDownstreamOnlyCheckBox_, &QCheckBox::stateChanged, this, &PreferencesWindow::updateModuleExecuteDownstream);
5251
connect(toolBarPopupShowDelaySpinBox_, qOverload<int>(&QSpinBox::valueChanged), this, &PreferencesWindow::updateToolBarPopupShowDelay);
5352
connect(toolBarPopupHideDelaySpinBox_, qOverload<int>(&QSpinBox::valueChanged), this, &PreferencesWindow::updateToolBarPopupHideDelay);
5453
}
5554

56-
void PreferencesWindow::updateWidgetSelectionCorrection(int state)
57-
{
58-
SCIRun::Core::Preferences::Instance().widgetSelectionCorrection.setValue(state != 0);
59-
}
60-
6155
void PreferencesWindow::updateToolBarPopupShowDelay(int delay)
6256
{
6357
SCIRun::Core::Preferences::Instance().toolBarPopupShowDelay.setValueWithSignal(delay);
@@ -133,12 +127,6 @@ void PreferencesWindow::setToolBarPopupHideDelay(int delay)
133127
updateToolBarPopupHideDelay(delay);
134128
}
135129

136-
void PreferencesWindow::setWidgetSelectionCorrection(bool mode)
137-
{
138-
updateWidgetSelectionCorrection(mode ? 1 : 0);
139-
viewerWidgetSelectionCorrectionCheckbox_->setChecked(mode);
140-
}
141-
142130
void PreferencesWindow::setHighDPIAdjustment(bool highDPI)
143131
{
144132
updateHighDPIAdjust(highDPI ? 1 : 0);

src/Interface/Application/PreferencesWindow.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class PreferencesWindow : public QDialog, public Ui::PreferencesDialog
5757
void setHighDPIAdjustment(bool highDPI);
5858
void setModuleExecuteDownstreamOnly(bool mode);
5959
void setAutoRotateViewerOnMouseRelease(bool mode);
60-
void setWidgetSelectionCorrection(bool mode);
6160
void setToolBarPopupShowDelay(int delay);
6261
void setToolBarPopupHideDelay(int delay);
6362

@@ -68,7 +67,6 @@ public Q_SLOTS:
6867
void updateAutoNotesState(int state);
6968
void updateHighDPIAdjust(int state);
7069
void updateForceGridBackground(int state);
71-
void updateWidgetSelectionCorrection(int state);
7270
void updateAutoRotateViewer(int state);
7371
void updateToolBarPopupShowDelay(int delay);
7472
void updateToolBarPopupHideDelay(int delay);

src/Interface/Application/Settings.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,6 @@ void SCIRunMainWindow::readSettings()
301301
makeSetting("invertMouseZoom", toBool,
302302
[](bool b) { prefs.invertMouseZoom.setValue(b); },
303303
[]() { return prefs.invertMouseZoom.val(); }),
304-
makeSetting("widgetSelectionCorrection", toBool,
305-
[this](bool b) { prefsWindow_->setWidgetSelectionCorrection(b); },
306-
[]() { return prefs.widgetSelectionCorrection.val(); }),
307304
makeSetting("autoRotateViewerOnMouseRelease", toBool,
308305
[this](bool b) { prefsWindow_->setAutoRotateViewerOnMouseRelease(b); },
309306
[]() { return prefs.autoRotateViewerOnMouseRelease.val(); }),

src/Interface/Modules/Render/ES/SRInterface.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,16 @@ void SRInterface::runGCOnNextExecution()
431431
widgetSelectFboId_ = fboMan->getOrCreateFBO(mCore, GL_TEXTURE_2D, screen_.width, screen_.height, 1, widgetSelectFboName);
432432
fboMan->bindFBO(*widgetSelectFboId_);
433433

434+
// The selection FBO matches the logical widget size that mouse coordinates
435+
// are reported in, but the inherited viewport is the on-screen framebuffer's,
436+
// which Qt scales by devicePixelRatio on high-DPI displays. Point the
437+
// viewport at the selection FBO so clip space maps onto it 1:1.
438+
GLint priorViewport[4];
439+
GL(glGetIntegerv(GL_VIEWPORT, priorViewport));
440+
GL(glViewport(0, 0, static_cast<GLsizei>(screen_.width), static_cast<GLsizei>(screen_.height)));
441+
ScopedLambdaExecutor restoreViewport([&priorViewport]()
442+
{ GL(glViewport(priorViewport[0], priorViewport[1], priorViewport[2], priorViewport[3])); });
443+
434444
//a map from selection id to name
435445
std::map<uint32_t, std::string> selMap;
436446
std::vector<uint64_t> entityList;
@@ -514,13 +524,11 @@ void SRInterface::runGCOnNextExecution()
514524
const char* vs =
515525
"uniform mat4 uModelViewProjection;\n"
516526
"uniform vec4 uColor;\n"
517-
"uniform bool hack;\n"
518527
"attribute vec3 aPos;\n"
519528
"varying vec4 fColor;\n"
520529
"void main()\n"
521530
"{\n"
522531
" gl_Position = uModelViewProjection * vec4(aPos, 1.0);\n"
523-
" if(hack) gl_Position.xy = ((gl_Position.xy/gl_Position.w) * vec2(0.5) - vec2(0.5)) * gl_Position.w;\n"
524532
" fColor = uColor;\n"
525533
"}\n";
526534
const char* fs =
@@ -555,7 +563,6 @@ void SRInterface::runGCOnNextExecution()
555563
mCore.addComponent(entityID, commonUniforms);
556564

557565
applyUniform(entityID, SpireSubPass::Uniform("uColor", selCol));
558-
applyUniform(entityID, SpireSubPass::Uniform("hack", Preferences::Instance().widgetSelectionCorrection));
559566

560567
// Add components associated with entity. We just need a base class which
561568
// we can pass in an entity ID, then a derived class which bundles

0 commit comments

Comments
 (0)