build/ci: green builds and tests on all three platforms

Compiler hygiene (all platforms):
- Silence warnings across the tree: missing override, -Wreorder ctor
  init, -Wshadow, -Wsign-compare, missing switch cases, unused
  functions/captures, Qt 6.11 deprecations (QMouseEvent/QDropEvent
  accessors, qAsConst, Q_FOREACH over non-shared containers,
  AA_UseHighDpiPixmaps) and the .bak/ backup tree removal.
- Fix regressions from the cleanup: missing clip decls in
  capi/timeline.cpp, plugin.cpp rename fallout, panel setFocus
  ambiguity, QGraphicsItem::pos vs event->position(), duplicate
  k_push_button case, boolean test variable.

Windows:
- Qt portability: CommandLineParser is_set/add_option, QTimeZone
  systemTimeZone (QTimeZone::LocalTime is 6.11-only), k_progress_* enum.
- Linking: stop adding oakengine to OLIVE_LIBRARIES (import lib plus
  oakengine-obj caused multiple definitions); add OAKENGINE_STATIC so
  internal consumers no longer reference __imp_* stubs.
- oakengine.ver: export olive::Renderer typeinfo so liboakgl.so can be
  dlopened (Linux), DynamicRenderer no longer dlcloses backend libraries
  (crash in RenderManager's dtor calling into unmapped memory).
- OTIO runtime: copy DLLs next to every binary on Windows instead of
  relying on PATH (0xc0000135 in gtest discovery).
- Headless GL: the runner only has GDI OpenGL 1.1, killing every render
  worker. Deploy Mesa llvmpipe as opengl32sw.dll (Qt's software-GL
  channel) with QT_OPENGL=software, and let QT_OPENGL override the
  AA_UseDesktopOpenGL default. ExportTask fails fast after 8 consecutive
  undelivered frames instead of segfaulting or grinding forever;
  FFmpegEncoder::write_frame tolerates null frames.
- Tests: GetTempPathA+PID temp dirs, GetLongPathNameA for 8.3 names,
  forward-slash normalization when comparing project filenames.

Linux:
- Install libshaderc-dev so oakvulkan compiles GLSL (Vulkan tests).
- Accept UNORM floor-or-round (63/64) in the blit ping-pong test.
- Skip MainWindow construction test on the offscreen QPA (cannot paint
  QOpenGLWidget).

Also: oak_cli_transcode gets a 300s ctest timeout, worker logs GL
context version and LoadGraph/render_frame stages, and
docs/plans/eliminate-event-bridge-issues.md (English translation).
This commit is contained in:
2026-08-04 21:34:31 +08:00
parent 5006382790
commit 712badbaa7
127 changed files with 826 additions and 8498 deletions
+9 -8
View File
@@ -19,6 +19,7 @@
***/
#include <utility>
#include "viewer.h"
#include <QDateTime>
@@ -172,11 +173,16 @@ const Rational k_video_playback_interval = Rational(1, 10);
ViewerWidget::ViewerWidget(ViewerDisplayWidget *display, QWidget *parent)
: super(false, true, parent)
, overlay_(nullptr)
, info_chip_(nullptr)
, safe_frame_btn_(nullptr)
, overlay_zoom_index_(5)
, playback_speed_(0)
, color_menu_enabled_(true)
, time_changed_from_timer_(false)
, prequeuing_video_(false)
, prequeuing_audio_(0)
, audio_processor_(oakengine_audio_processor_create())
, record_armed_(false)
, recording_(false)
, first_requeue_watcher_(nullptr)
@@ -185,11 +191,6 @@ ViewerWidget::ViewerWidget(ViewerDisplayWidget *display, QWidget *parent)
, ignore_scrub_(0)
, multicam_panel_(nullptr)
, bridge_(new EngineEventBridge(this))
, audio_processor_(oakengine_audio_processor_create())
, overlay_(nullptr)
, info_chip_(nullptr)
, safe_frame_btn_(nullptr)
, overlay_zoom_index_(5)
{
// Set up main layout
QVBoxLayout *layout = new QVBoxLayout(this);
@@ -958,13 +959,13 @@ void ViewerWidget::detect_multicam_node(const Rational &time)
const Rational seq_tb = sequence_timebase(seq);
// Prefer selected nodes
for (OakEngineNode *n : qAsConst(node_view_selected_)) {
for (OakEngineNode *n : std::as_const(node_view_selected_)) {
// MultiCam check via facade predicate (replaces
// dynamic_cast<MultiCamNode*>)
if (oakengine_node_is_multicam(n)) {
multicam = n;
// Found multicam, now try to find corresponding clip from selected timeline blocks
for (OakEngineBlock *b : qAsConst(timeline_selected_blocks_)) {
for (OakEngineBlock *b : std::as_const(timeline_selected_blocks_)) {
// Clip check via facade predicate (replaces
// dynamic_cast<ClipBlock*>)
if (oakengine_node_is_clip(
@@ -983,7 +984,7 @@ void ViewerWidget::detect_multicam_node(const Rational &time)
// Next, prefer multicam from selected block
if (!multicam) {
for (OakEngineBlock *b : qAsConst(timeline_selected_blocks_)) {
for (OakEngineBlock *b : std::as_const(timeline_selected_blocks_)) {
if (block_range_contains(b, seq_tb, time) &&
oakengine_node_is_clip(
reinterpret_cast<OakEngineNode *>(b))) {
+23 -23
View File
@@ -69,6 +69,7 @@ ViewerDisplayWidget::ViewerDisplayWidget(QWidget *parent)
, blank_shader_(nullptr)
, signal_cursor_color_(false)
, gizmos_(nullptr)
, gizmo_params_(empty_video_params())
, current_gizmo_(nullptr)
, gizmo_drag_started_(false)
, show_subtitles_(true)
@@ -83,7 +84,6 @@ ViewerDisplayWidget::ViewerDisplayWidget(QWidget *parent)
, add_band_(false)
, queue_starved_(false)
, text_edit_(nullptr)
, gizmo_params_(empty_video_params())
{
connect(Core::instance(), &Core::tool_changed, this,
&ViewerDisplayWidget::tool_changed);
@@ -1083,7 +1083,7 @@ void ViewerDisplayWidget::open_text_gizmo(void *text, QMouseEvent *event)
// Start text cursor where the user clicked
if (event) {
QPoint click_pos = text_transform_inverted_.map(event->pos()) -
QPoint click_pos = text_transform_inverted_.map(event->position().toPoint()) -
text_edit_pos_.toPoint();
text_edit_->setTextCursor(text_edit_->cursorForPosition(click_pos));
}
@@ -1099,7 +1099,7 @@ bool ViewerDisplayWidget::on_mouse_press(QMouseEvent *event)
{
if (is_hand_drag(event)) {
// Handle hand drag
hand_last_drag_pos_ = event->pos();
hand_last_drag_pos_ = event->position().toPoint();
hand_dragging_ = true;
emit hand_drag_started();
inner_widget()->setCursor(Qt::ClosedHandCursor);
@@ -1115,15 +1115,15 @@ bool ViewerDisplayWidget::on_mouse_press(QMouseEvent *event)
Tool::k_addable_shape ||
Core::instance()->get_selected_addable_object() ==
Tool::k_addable_title)) {
add_band_start_ = event->pos();
add_band_start_ = event->position().toPoint();
add_band_end_ = add_band_start_;
add_band_ = true;
} else if ((current_gizmo_ = try_gizmo_press(
gizmo_last_draw_transform_inverted_.map(
event->pos())))) {
event->position().toPoint())))) {
// Handle gizmo click
gizmo_start_drag_ = event->pos();
gizmo_start_drag_ = event->position().toPoint();
gizmo_last_drag_ = gizmo_start_drag_;
const TimeRange gizmo_time = generate_gizmo_time();
oakengine_gizmo_set_globals(
@@ -1132,7 +1132,7 @@ bool ViewerDisplayWidget::on_mouse_press(QMouseEvent *event)
} else {
// Handle standard drag
emit drag_started(event->pos());
emit drag_started(event->position().toPoint());
}
return true;
@@ -1146,10 +1146,10 @@ bool ViewerDisplayWidget::on_mouse_move(QMouseEvent *event)
// Handle hand dragging
if (hand_dragging_) {
// Emit movement
emit hand_drag_moved(event->x() - hand_last_drag_pos_.x(),
event->y() - hand_last_drag_pos_.y());
emit hand_drag_moved(event->position().toPoint().x() - hand_last_drag_pos_.x(),
event->position().toPoint().y() - hand_last_drag_pos_.y());
hand_last_drag_pos_ = event->pos();
hand_last_drag_pos_ = event->position().toPoint();
return true;
@@ -1157,7 +1157,7 @@ bool ViewerDisplayWidget::on_mouse_move(QMouseEvent *event)
return true;
} else if (add_band_) {
add_band_end_ = event->pos();
add_band_end_ = event->position().toPoint();
update();
return true;
@@ -1184,11 +1184,11 @@ bool ViewerDisplayWidget::on_mouse_move(QMouseEvent *event)
gizmo_drag_started_ = true;
}
QPointF v = screen_to_scene_point(event->pos());
QPointF v = screen_to_scene_point(event->position().toPoint());
switch (drag_behavior) {
case 1:
v -= screen_to_scene_point(gizmo_last_drag_);
gizmo_last_drag_ = event->pos();
gizmo_last_drag_ = event->position().toPoint();
break;
case 2:
v -= screen_to_scene_point(gizmo_start_drag_);
@@ -1249,7 +1249,7 @@ bool ViewerDisplayWidget::on_mouse_double_click(QMouseEvent *event)
if (text_edit_ && forward_mouse_event_to_text_edit(event)) {
return true;
} else if (event->button() == Qt::LeftButton && gizmos_) {
QPointF ptr = transform_viewer_space_to_buffer_space(event->pos());
QPointF ptr = transform_viewer_space_to_buffer_space(event->position().toPoint());
OakEngineNode *gizmos_handle =
gizmos_;
// A text gizmo only exists on a text v3 node, so the node type id is
@@ -1303,7 +1303,7 @@ void ViewerDisplayWidget::emit_color_at_cursor(QMouseEvent *e)
if (texture_) {
QPointF pixel_pos =
generate_display_transform().inverted().map(e->pos());
generate_display_transform().inverted().map(e->position().toPoint());
oak_video_params tp = {};
oakengine_display_texture_get_params(texture_, &tp);
pixel_pos /= (tp.divider > 0 ? tp.divider : 1);
@@ -1458,9 +1458,9 @@ template <typename T> void ViewerDisplayWidget::forward_drag_event_to_text_edit(
if constexpr (std::is_same_v<T, QDragLeaveEvent>) {
text_edit_->dragLeaveEvent(e);
} else {
T relay(adjust_pos_by_v_align(get_virtual_pos_for_text_edit(e->pos())).toPoint(),
e->possibleActions(), e->mimeData(), e->mouseButtons(),
e->keyboardModifiers());
T relay(adjust_pos_by_v_align(get_virtual_pos_for_text_edit(e->position().toPoint())).toPoint(),
e->possibleActions(), e->mimeData(), e->buttons(),
e->modifiers());
if (e->type() == QEvent::DragEnter) {
text_edit_->dragEnterEvent(static_cast<QDragEnterEvent *>(&relay));
@@ -1484,12 +1484,12 @@ bool ViewerDisplayWidget::forward_mouse_event_to_text_edit(QMouseEvent *event,
}
// Transform screen mouse coords to world mouse coords
QPointF local_pos = get_virtual_pos_for_text_edit(event->pos());
QPointF local_pos = get_virtual_pos_for_text_edit(event->position().toPoint());
if (event->type() == QEvent::MouseMove &&
event->buttons() == Qt::NoButton) {
QPointF mapped =
text_transform_inverted_.map(event->pos()) - text_edit_pos_;
text_transform_inverted_.map(event->position().toPoint()) - text_edit_pos_;
if (mapped.x() >= 0 && mapped.y() >= 0 &&
mapped.x() < text_edit_->width() &&
mapped.y() < text_edit_->height()) {
@@ -1504,7 +1504,7 @@ bool ViewerDisplayWidget::forward_mouse_event_to_text_edit(QMouseEvent *event,
local_pos.y() < 0 || local_pos.y() >= text_edit_->height()) {
// Allow clicking other gizmos so the user can resize while the text editor is active
if ((current_gizmo_ = try_gizmo_press(
gizmo_last_draw_transform_inverted_.map(event->pos())))) {
gizmo_last_draw_transform_inverted_.map(event->position().toPoint())))) {
return false;
} else {
close_text_editor();
@@ -1515,8 +1515,8 @@ bool ViewerDisplayWidget::forward_mouse_event_to_text_edit(QMouseEvent *event,
local_pos = adjust_pos_by_v_align(local_pos);
QMouseEvent derived(event->type(), local_pos, event->windowPos(),
event->screenPos(), event->button(), event->buttons(),
QMouseEvent derived(event->type(), local_pos, event->scenePosition(),
event->globalPosition(), event->button(), event->buttons(),
event->modifiers(), event->source());
return forward_event_to_text_edit(&derived);
}
+4 -4
View File
@@ -185,7 +185,7 @@ void ViewerTextEditor::update_tool_bar(ViewerTextEditorToolBar *toolbar,
}
QString style = f.fontStyleName().toString();
QStringList styles = QFontDatabase().styles(family);
QStringList styles = QFontDatabase::styles(family);
if (!styles.isEmpty() && (style.isEmpty() || !styles.contains(style))) {
// There seems to be no better way to find the "regular" style outside of this heuristic.
// Feel free to add more if a font isn't working right.
@@ -298,8 +298,8 @@ void ViewerTextEditor::apply_style(QTextCharFormat *format,
{
// NOTE: Windows appears to require setting weight and italic manually, while macOS and Linux are
// perfectly fine with just the style name
format->setFontWeight(QFontDatabase().weight(family, style));
format->setFontItalic(QFontDatabase().italic(family, style));
format->setFontWeight(QFontDatabase::weight(family, style));
format->setFontItalic(QFontDatabase::italic(family, style));
format->setFontStyleName(style);
}
@@ -594,7 +594,7 @@ void ViewerTextEditorToolBar::update_font_style_list(const QString &family)
style_combo_->blockSignals(true);
style_combo_->clear();
QStringList l = QFontDatabase().styles(family);
QStringList l = QFontDatabase::styles(family);
foreach (const QString &style, l) {
style_combo_->addItem(style);
}