diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini
index 096c860d1..d93b16593 100644
--- a/UI/data/locale/en-US.ini
+++ b/UI/data/locale/en-US.ini
@@ -390,8 +390,8 @@ Deinterlacing.TopFieldFirst="Top Field First"
Deinterlacing.BottomFieldFirst="Bottom Field First"
# volume control accessibility text
-VolControl.SliderUnmuted="Volume slider for '%1': %2"
-VolControl.SliderMuted="Volume slider for '%1': %2 (currently muted)"
+VolControl.SliderUnmuted="Volume slider for '%1':"
+VolControl.SliderMuted="Volume slider for '%1': (currently muted)"
VolControl.Mute="Mute '%1'"
VolControl.Properties="Properties for '%1'"
@@ -430,6 +430,12 @@ Basic.SourceSelect.CreateNew="Create new"
Basic.SourceSelect.AddExisting="Add Existing"
Basic.SourceSelect.AddVisible="Make source visible"
+# source box
+Basic.Main.Sources.Visibility="Visibility"
+Basic.Main.Sources.VisibilityDescription="Controls the visibility of '%1' in the canvas"
+Basic.Main.Sources.Lock="Lock"
+Basic.Main.Sources.LockDescription="Locks the position and scale of '%1' in the canvas"
+
# properties window
Basic.PropertiesWindow="Properties for '%1'"
Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselect: %2)"
@@ -733,6 +739,7 @@ Basic.Settings.Output.Adv.Audio.Track6="Track 6"
# basic mode 'output' settings - advanced section - recording subsection
Basic.Settings.Output.Adv.Recording="Recording"
+Basic.Settings.Output.Adv.Recording.RecType="Recording Type"
Basic.Settings.Output.Adv.Recording.Type="Type"
Basic.Settings.Output.Adv.Recording.Type.Standard="Standard"
Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Custom Output (FFmpeg)"
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index a10e48277..e00325843 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -371,33 +371,13 @@
- -
-
+
-
+
- Basic.Settings.General.ScreenSnapping
+ Basic.Settings.General.SnapDistance
-
- true
-
-
-
- -
-
-
- Basic.Settings.General.CenterSnapping
-
-
- true
-
-
-
- -
-
-
- Basic.Settings.General.SourceSnapping
-
-
- true
+
+ snapDistance
@@ -414,13 +394,13 @@
- -
-
+
-
+
- Basic.Settings.General.SnapDistance
+ Basic.Settings.General.ScreenSnapping
-
- snapDistance
+
+ true
@@ -440,6 +420,26 @@
+ -
+
+
+ Basic.Settings.General.SourceSnapping
+
+
+ true
+
+
+
+ -
+
+
+ Basic.Settings.General.CenterSnapping
+
+
+ true
+
+
+
@@ -568,13 +568,6 @@
2
- -
-
-
- Basic.Settings.General.OverflowAlwaysVisible
-
-
-
-
@@ -588,13 +581,6 @@
- -
-
-
- Basic.Settings.General.OverflowSelectionHidden
-
-
-
-
@@ -602,6 +588,20 @@
+ -
+
+
+ Basic.Settings.General.OverflowAlwaysVisible
+
+
+
+ -
+
+
+ Basic.Settings.General.OverflowSelectionHidden
+
+
+
@@ -721,9 +721,6 @@
- -
-
-
-
@@ -734,6 +731,9 @@
+ -
+
+
@@ -4636,6 +4636,16 @@
+ -
+
+
+ Basic.Settings.Advanced.Video.ColorSpace
+
+
+ colorSpace
+
+
+
-
@@ -4685,16 +4695,6 @@
- -
-
-
- Basic.Settings.Advanced.Video.ColorSpace
-
-
- colorSpace
-
-
-
-
@@ -4746,6 +4746,23 @@
+ -
+
+
+ Basic.Settings.Advanced.AutoRemux
+
+
+
+ -
+
+
+ Basic.Settings.Output.ReplayBuffer.Prefix
+
+
+ simpleRBPrefix
+
+
+
-
@@ -4778,16 +4795,6 @@
- -
-
-
- Basic.Settings.Output.ReplayBuffer.Prefix
-
-
- simpleRBPrefix
-
-
-
-
@@ -4801,13 +4808,6 @@
- -
-
-
- Basic.Settings.Advanced.AutoRemux
-
-
-
-
@@ -4839,6 +4839,16 @@
2
+
-
+
+
+ Enable
+
+
+ true
+
+
+
-
@@ -4915,16 +4925,6 @@
- -
-
-
- Enable
-
-
- true
-
-
-
-
@@ -4966,6 +4966,16 @@
+ -
+
+
+ Basic.Settings.Output.RetryDelay
+
+
+ reconnectRetryDelay
+
+
+
-
@@ -5018,16 +5028,6 @@
- -
-
-
- Basic.Settings.Output.RetryDelay
-
-
- reconnectRetryDelay
-
-
-
-
@@ -5072,6 +5072,16 @@
-
+ -
+
+
+ Basic.Settings.Output.DynamicBitrate.TT
+
+
+ Basic.Settings.Output.DynamicBitrate.Beta
+
+
+
-
@@ -5102,16 +5112,6 @@
- -
-
-
- Basic.Settings.Output.DynamicBitrate.TT
-
-
- Basic.Settings.Output.DynamicBitrate.Beta
-
-
-
diff --git a/UI/hotkey-edit.cpp b/UI/hotkey-edit.cpp
index 37e5a7d4d..2ee0cc39b 100644
--- a/UI/hotkey-edit.cpp
+++ b/UI/hotkey-edit.cpp
@@ -293,11 +293,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
auto add = new QPushButton;
add->setProperty("themeID", "addIconSmall");
+ add->setToolTip(QTStr("Add"));
add->setFixedSize(24, 24);
add->setFlat(true);
auto remove = new QPushButton;
remove->setProperty("themeID", "removeIconSmall");
+ remove->setToolTip(QTStr("Remove"));
remove->setEnabled(removeButtons.size() > 0);
remove->setFixedSize(24, 24);
remove->setFlat(true);
diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp
index 46967e650..5051b433d 100644
--- a/UI/obs-app.cpp
+++ b/UI/obs-app.cpp
@@ -34,9 +34,11 @@
#include
#include
#include
+#include
#include "qt-wrappers.hpp"
#include "obs-app.hpp"
+#include "slider-ignorewheel.hpp"
#include "window-basic-main.hpp"
#include "window-basic-settings.hpp"
#include "crash-report.hpp"
@@ -1720,6 +1722,17 @@ static auto ProfilerFree = [](void *) {
profiler_free();
};
+QAccessibleInterface *accessibleFactory(const QString &classname,
+ QObject *object)
+{
+ if (classname == QLatin1String("VolumeSlider") && object &&
+ object->isWidgetType())
+ return new VolumeAccessibleInterface(
+ static_cast(object));
+
+ return nullptr;
+}
+
static const char *run_program_init = "run_program_init";
static int run_program(fstream &logFile, int argc, char *argv[])
{
@@ -1743,6 +1756,8 @@ static int run_program(fstream &logFile, int argc, char *argv[])
OBSApp program(argc, argv, profilerNameStore.get());
try {
+ QAccessible::installFactory(accessibleFactory);
+
bool created_log = false;
program.AppInit();
diff --git a/UI/slider-ignorewheel.cpp b/UI/slider-ignorewheel.cpp
index 8203c81f9..dea80c18f 100644
--- a/UI/slider-ignorewheel.cpp
+++ b/UI/slider-ignorewheel.cpp
@@ -1,4 +1,5 @@
#include "slider-ignorewheel.hpp"
+#include "volume-control.hpp"
SliderIgnoreScroll::SliderIgnoreScroll(QWidget *parent) : QSlider(parent)
{
@@ -20,3 +21,82 @@ void SliderIgnoreScroll::wheelEvent(QWheelEvent *event)
else
QSlider::wheelEvent(event);
}
+
+VolumeSlider::VolumeSlider(obs_fader_t *fader, QWidget *parent)
+ : SliderIgnoreScroll(parent)
+{
+ fad = fader;
+}
+
+VolumeSlider::VolumeSlider(obs_fader_t *fader, Qt::Orientation orientation,
+ QWidget *parent)
+ : SliderIgnoreScroll(orientation, parent)
+{
+ fad = fader;
+}
+
+VolumeAccessibleInterface::VolumeAccessibleInterface(QWidget *w)
+ : QAccessibleWidget(w)
+{
+}
+
+VolumeSlider *VolumeAccessibleInterface::slider() const
+{
+ return qobject_cast(object());
+}
+
+QString VolumeAccessibleInterface::text(QAccessible::Text t) const
+{
+ if (slider()->isVisible()) {
+ switch (t) {
+ case QAccessible::Text::Value:
+ return currentValue().toString();
+ default:
+ break;
+ }
+ }
+ return QAccessibleWidget::text(t);
+}
+
+QVariant VolumeAccessibleInterface::currentValue() const
+{
+ QString text;
+ float db = obs_fader_get_db(slider()->fad);
+
+ if (db < -96.0f)
+ text = "-inf dB";
+ else
+ text = QString::number(db, 'f', 1).append(" dB");
+
+ return text;
+}
+
+void VolumeAccessibleInterface::setCurrentValue(const QVariant &value)
+{
+ slider()->setValue(value.toInt());
+}
+
+QVariant VolumeAccessibleInterface::maximumValue() const
+{
+ return slider()->maximum();
+}
+
+QVariant VolumeAccessibleInterface::minimumValue() const
+{
+ return slider()->minimum();
+}
+
+QVariant VolumeAccessibleInterface::minimumStepSize() const
+{
+ return slider()->singleStep();
+}
+
+QAccessible::Role VolumeAccessibleInterface::role() const
+{
+ return QAccessible::Role::Slider;
+}
+
+/**QAccessible::State VolumeAccessibleInterface::state() const
+{
+ return QAccessible::State::
+}**/
diff --git a/UI/slider-ignorewheel.hpp b/UI/slider-ignorewheel.hpp
index f5c7e5d72..40d04487c 100644
--- a/UI/slider-ignorewheel.hpp
+++ b/UI/slider-ignorewheel.hpp
@@ -1,8 +1,10 @@
#pragma once
+#include "obs.hpp"
#include
#include
#include
+#include
class SliderIgnoreScroll : public QSlider {
Q_OBJECT
@@ -15,3 +17,35 @@ public:
protected:
virtual void wheelEvent(QWheelEvent *event) override;
};
+
+class VolumeSlider : public SliderIgnoreScroll {
+ Q_OBJECT
+
+public:
+ obs_fader_t *fad;
+
+ VolumeSlider(obs_fader_t *fader, QWidget *parent = nullptr);
+ VolumeSlider(obs_fader_t *fader, Qt::Orientation orientation,
+ QWidget *parent = nullptr);
+};
+
+class VolumeAccessibleInterface : public QAccessibleWidget {
+
+public:
+ VolumeAccessibleInterface(QWidget *w);
+
+ QVariant currentValue() const;
+ void setCurrentValue(const QVariant &value);
+
+ QVariant maximumValue() const;
+ QVariant minimumValue() const;
+
+ QVariant minimumStepSize() const;
+
+private:
+ VolumeSlider *slider() const;
+
+protected:
+ virtual QAccessible::Role role() const override;
+ virtual QString text(QAccessible::Text t) const override;
+};
diff --git a/UI/source-tree.cpp b/UI/source-tree.cpp
index 4032f3a3e..083a85de5 100644
--- a/UI/source-tree.cpp
+++ b/UI/source-tree.cpp
@@ -62,12 +62,18 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
vis->setFixedSize(16, 16);
vis->setChecked(obs_sceneitem_visible(sceneitem));
vis->setStyleSheet("background: none");
+ vis->setAccessibleName(QTStr("Basic.Main.Sources.Visibility"));
+ vis->setAccessibleDescription(
+ QTStr("Basic.Main.Sources.VisibilityDescription").arg(name));
lock = new LockedCheckBox();
lock->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
lock->setFixedSize(16, 16);
lock->setChecked(obs_sceneitem_locked(sceneitem));
lock->setStyleSheet("background: none");
+ lock->setAccessibleName(QTStr("Basic.Main.Sources.Lock"));
+ lock->setAccessibleDescription(
+ QTStr("Basic.Main.Sources.LockDescription").arg(name));
label = new QLabel(QT_UTF8(name));
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
@@ -107,8 +113,8 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
obs_sceneitem_set_locked(sceneitem, checked);
};
- connect(vis, &QAbstractButton::clicked, setItemVisible);
- connect(lock, &QAbstractButton::clicked, setItemLocked);
+ connect(vis, &QAbstractButton::toggled, setItemVisible);
+ connect(lock, &QAbstractButton::toggled, setItemLocked);
}
void SourceTreeItem::paintEvent(QPaintEvent *event)
diff --git a/UI/volume-control.cpp b/UI/volume-control.cpp
index 35fdb0c2a..51d5bc4d5 100644
--- a/UI/volume-control.cpp
+++ b/UI/volume-control.cpp
@@ -89,7 +89,7 @@ void VolControl::updateText()
: "VolControl.SliderUnmuted";
QString sourceName = obs_source_get_name(source);
- QString accText = QTStr(accTextLookup).arg(sourceName, db);
+ QString accText = QTStr(accTextLookup).arg(sourceName);
slider->setAccessibleName(accText);
}
@@ -161,7 +161,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
QHBoxLayout *meterLayout = new QHBoxLayout;
volMeter = new VolumeMeter(nullptr, obs_volmeter, true);
- slider = new SliderIgnoreScroll(Qt::Vertical);
+ slider = new VolumeSlider(obs_fader, Qt::Vertical);
nameLayout->setAlignment(Qt::AlignCenter);
meterLayout->setAlignment(Qt::AlignCenter);
@@ -205,7 +205,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
QHBoxLayout *botLayout = new QHBoxLayout;
volMeter = new VolumeMeter(nullptr, obs_volmeter, false);
- slider = new SliderIgnoreScroll(Qt::Horizontal);
+ slider = new VolumeSlider(obs_fader, Qt::Horizontal);
textLayout->setContentsMargins(0, 0, 0, 0);
textLayout->addWidget(nameLabel);
@@ -254,7 +254,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
QWidget::connect(slider, SIGNAL(valueChanged(int)), this,
SLOT(SliderChanged(int)));
- QWidget::connect(mute, SIGNAL(clicked(bool)), this,
+ QWidget::connect(mute, SIGNAL(toggled(bool)), this,
SLOT(SetMuted(bool)));
obs_fader_attach_source(obs_fader, source);
diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp
index 0980dd297..9f503b32d 100644
--- a/UI/window-basic-main.cpp
+++ b/UI/window-basic-main.cpp
@@ -1486,7 +1486,7 @@ void OBSBasic::ResetOutputs()
QTStr("Basic.Main.StartReplayBuffer"), this);
replayBufferButton->setCheckable(true);
connect(replayBufferButton.data(),
- &QPushButton::clicked, this,
+ &QPushButton::toggled, this,
&OBSBasic::ReplayBufferClicked);
replayBufferButton->setProperty("themeID",
@@ -7506,7 +7506,7 @@ void OBSBasic::UpdatePause(bool activate)
pause->setChecked(false);
pause->setProperty("themeID",
QVariant(QStringLiteral("pauseIconSmall")));
- connect(pause.data(), &QAbstractButton::clicked, this,
+ connect(pause.data(), &QAbstractButton::toggled, this,
&OBSBasic::PauseToggled);
ui->recordingLayout->addWidget(pause.data());
} else {
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index 4d10e72d2..1a2d29c37 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -260,10 +260,9 @@ void OBSBasicSettings::HookWidget(QWidget *widget, const char *signal,
#define COMBO_CHANGED SIGNAL(currentIndexChanged(int))
#define EDIT_CHANGED SIGNAL(textChanged(const QString &))
#define CBEDIT_CHANGED SIGNAL(editTextChanged(const QString &))
-#define CHECK_CHANGED SIGNAL(clicked(bool))
+#define CHECK_CHANGED SIGNAL(toggled(bool))
#define SCROLL_CHANGED SIGNAL(valueChanged(int))
#define DSCROLL_CHANGED SIGNAL(valueChanged(double))
-#define TOGGLE_CHANGED SIGNAL(toggled(bool))
#define GENERAL_CHANGED SLOT(GeneralChanged())
#define STREAM1_CHANGED SLOT(Stream1Changed())
@@ -726,18 +725,68 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
InitStreamPage();
LoadSettings(false);
+ ui->advOutTrack1->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track1"));
+ ui->advOutTrack2->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track2"));
+ ui->advOutTrack3->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track3"));
+ ui->advOutTrack4->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track4"));
+ ui->advOutTrack5->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track5"));
+ ui->advOutTrack6->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track6"));
+
+ ui->advOutRecTrack1->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track1"));
+ ui->advOutRecTrack2->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track2"));
+ ui->advOutRecTrack3->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track3"));
+ ui->advOutRecTrack4->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track4"));
+ ui->advOutRecTrack5->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track5"));
+ ui->advOutRecTrack6->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track6"));
+
+ ui->advOutFFTrack1->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track1"));
+ ui->advOutFFTrack2->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track2"));
+ ui->advOutFFTrack3->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track3"));
+ ui->advOutFFTrack4->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track4"));
+ ui->advOutFFTrack5->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track5"));
+ ui->advOutFFTrack6->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Audio.Track6"));
+
+ ui->snappingEnabled->setAccessibleName(
+ QTStr("Basic.Settings.General.Snapping"));
+ ui->systemTrayEnabled->setAccessibleName(
+ QTStr("Basic.Settings.General.SysTray"));
+ ui->label_31->setAccessibleName(
+ QTStr("Basic.Settings.Output.Adv.Recording.RecType"));
+ ui->streamDelayEnable->setAccessibleName(
+ QTStr("Basic.Settings.Advanced.StreamDelay"));
+ ui->reconnectEnable->setAccessibleName(
+ QTStr("Basic.Settings.Output.Reconnect"));
+
// Add warning checks to advanced output recording section controls
- connect(ui->advOutRecTrack1, SIGNAL(clicked()), this,
+ connect(ui->advOutRecTrack1, SIGNAL(toggled()), this,
SLOT(AdvOutRecCheckWarnings()));
- connect(ui->advOutRecTrack2, SIGNAL(clicked()), this,
+ connect(ui->advOutRecTrack2, SIGNAL(toggled()), this,
SLOT(AdvOutRecCheckWarnings()));
- connect(ui->advOutRecTrack3, SIGNAL(clicked()), this,
+ connect(ui->advOutRecTrack3, SIGNAL(toggled()), this,
SLOT(AdvOutRecCheckWarnings()));
- connect(ui->advOutRecTrack4, SIGNAL(clicked()), this,
+ connect(ui->advOutRecTrack4, SIGNAL(toggled()), this,
SLOT(AdvOutRecCheckWarnings()));
- connect(ui->advOutRecTrack5, SIGNAL(clicked()), this,
+ connect(ui->advOutRecTrack5, SIGNAL(toggled()), this,
SLOT(AdvOutRecCheckWarnings()));
- connect(ui->advOutRecTrack6, SIGNAL(clicked()), this,
+ connect(ui->advOutRecTrack6, SIGNAL(toggled()), this,
SLOT(AdvOutRecCheckWarnings()));
connect(ui->advOutRecFormat, SIGNAL(currentIndexChanged(int)), this,
SLOT(AdvOutRecCheckWarnings()));