Skip to content

Commit 714d70c

Browse files
Merge pull request #87 from johanberntsson/fix/map-copy-paste-crash
Fix crash and menu no-op in map copy/paste
2 parents cfc27bd + 759d6f9 commit 714d70c

6 files changed

Lines changed: 99 additions & 7 deletions

File tree

CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,29 @@ if(NOT DEFINED INSTALL_DIR)
1111
endif()
1212

1313
find_package(Qt6 REQUIRED COMPONENTS Widgets LinguistTools)
14+
15+
# Fix macOS CI build failure due to AGL framework removal in macOS 14+ SDK
16+
if(APPLE)
17+
foreach(_target WrapOpenGL::WrapOpenGL Qt6::Gui Qt::Gui Qt6::Gui_private Qt::Gui_private)
18+
if(TARGET ${_target})
19+
get_target_property(_libs ${_target} INTERFACE_LINK_LIBRARIES)
20+
if(_libs)
21+
set(_new_libs "")
22+
set(_changed FALSE)
23+
foreach(_lib ${_libs})
24+
if(_lib MATCHES "AGL" OR _lib STREQUAL "AGL")
25+
set(_changed TRUE)
26+
else()
27+
list(APPEND _new_libs "${_lib}")
28+
endif()
29+
endforeach()
30+
if(_changed)
31+
set_target_properties(${_target} PROPERTIES INTERFACE_LINK_LIBRARIES "${_new_libs}")
32+
endif()
33+
endif()
34+
endif()
35+
endforeach()
36+
endif()
1437
qt_standard_project_setup(
1538
I18N_SOURCE_LANGUAGE en
1639
I18N_TRANSLATED_LANGUAGES es

src/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,29 @@ find_package(Qt6
8484
REQUIRED
8585
)
8686

87+
# Fix macOS CI build failure due to AGL framework removal in macOS 14+ SDK
88+
if(APPLE)
89+
foreach(_target WrapOpenGL::WrapOpenGL Qt6::Gui Qt::Gui Qt6::Gui_private Qt::Gui_private)
90+
if(TARGET ${_target})
91+
get_target_property(_libs ${_target} INTERFACE_LINK_LIBRARIES)
92+
if(_libs)
93+
set(_new_libs "")
94+
set(_changed FALSE)
95+
foreach(_lib ${_libs})
96+
if(_lib MATCHES "AGL" OR _lib STREQUAL "AGL")
97+
set(_changed TRUE)
98+
else()
99+
list(APPEND _new_libs "${_lib}")
100+
endif()
101+
endforeach()
102+
if(_changed)
103+
set_target_properties(${_target} PROPERTIES INTERFACE_LINK_LIBRARIES "${_new_libs}")
104+
endif()
105+
endif()
106+
endif()
107+
endforeach()
108+
endif()
109+
87110
qt_add_big_resources(RESOURCES
88111
resources.qrc
89112
)

src/mainwindow.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ limitations under the License.
2626
#include <QDir>
2727
#include <QDockWidget>
2828
#include <QErrorMessage>
29+
#include <QEvent>
2930
#include <QFileDialog>
3031
#include <QFileInfo>
3132
#include <QGuiApplication>
@@ -98,6 +99,12 @@ MainWindow::MainWindow(QWidget* parent)
9899
setupMapDock();
99100
setupStatusBar();
100101
checkForUpdates();
102+
103+
// needed so Copy/Paste (triggered from the Edit menu) know which widget
104+
// was last being edited, since opening the menu steals keyboard focus
105+
_ui->charsetWidget->installEventFilter(this);
106+
_ui->tilesetWidget->installEventFilter(this);
107+
_ui->mapWidget->installEventFilter(this);
101108
}
102109

103110
MainWindow::~MainWindow()
@@ -246,6 +253,15 @@ void MainWindow::closeEvent(QCloseEvent* event)
246253
}
247254
}
248255

256+
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
257+
{
258+
if (event->type() == QEvent::FocusIn
259+
&& (watched == _ui->charsetWidget || watched == _ui->tilesetWidget || watched == _ui->mapWidget)) {
260+
_lastFocusedEditorWidget = qobject_cast<QWidget*>(watched);
261+
}
262+
return QMainWindow::eventFilter(watched, event);
263+
}
264+
249265
void MainWindow::createUndoView()
250266
{
251267
auto undoDock = new QDockWidget(tr("Undo List"), this);
@@ -1268,8 +1284,8 @@ void MainWindow::on_actionPaste_triggered()
12681284
// src: TILES dst: Charset / Tileset
12691285
// src: MAP dst: Map
12701286
if (!(((range->type == State::CopyRange::CHARS || range->type == State::CopyRange::TILES)
1271-
&& (_ui->charsetWidget->hasFocus() || _ui->tilesetWidget->hasFocus()))
1272-
|| (range->type == State::CopyRange::MAP && _ui->mapWidget->hasFocus()))) {
1287+
&& (_lastFocusedEditorWidget == _ui->charsetWidget || _lastFocusedEditorWidget == _ui->tilesetWidget))
1288+
|| (range->type == State::CopyRange::MAP && _lastFocusedEditorWidget == _ui->mapWidget))) {
12731289
QApplication::beep();
12741290
return;
12751291
}
@@ -1579,11 +1595,11 @@ State* MainWindow::getState() const
15791595
State::CopyRange MainWindow::bufferToClipboard(State* state) const
15801596
{
15811597
State::CopyRange copyRange = {};
1582-
if (_ui->charsetWidget->hasFocus()) {
1598+
if (_lastFocusedEditorWidget == _ui->charsetWidget) {
15831599
_ui->charsetWidget->getSelectionRange(&copyRange);
1584-
} else if (_ui->tilesetWidget->hasFocus()) {
1600+
} else if (_lastFocusedEditorWidget == _ui->tilesetWidget) {
15851601
_ui->tilesetWidget->getSelectionRange(&copyRange);
1586-
} else if (_ui->mapWidget->hasFocus()) {
1602+
} else if (_lastFocusedEditorWidget == _ui->mapWidget) {
15871603
_ui->mapWidget->getSelectionRange(&copyRange);
15881604
} else {
15891605
copyRange.offset = -1;

src/mainwindow.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ QT_BEGIN_NAMESPACE
2626
class QUndoView;
2727
class QLabel;
2828
class QMdiSubWindow;
29-
class QUndoView;
3029
class QSpinBox;
3130
class QComboBox;
31+
class QEvent;
32+
class QCloseEvent;
3233
QT_END_NAMESPACE
3334

3435
namespace Ui {
@@ -122,6 +123,7 @@ public slots:
122123
void updateMenus();
123124

124125
void closeEvent(QCloseEvent* event) override;
126+
bool eventFilter(QObject* watched, QEvent* event) override;
125127

126128
BigCharWidget* getBigcharWidget() const;
127129
State* getState() const;
@@ -235,4 +237,9 @@ private slots:
235237

236238
// FIXME: Should be moved to the "charset dock" once it is implemented
237239
QComboBox* _comboBoxTilesetZoom;
240+
241+
// Tracks whichever of charsetWidget/tilesetWidget/mapWidget last had keyboard focus.
242+
// Needed because triggering Copy/Paste from the Edit menu momentarily steals focus
243+
// away from these widgets, so a plain hasFocus() check fails at that point.
244+
QWidget* _lastFocusedEditorWidget = nullptr;
238245
};

src/state.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ void State::_pasteMap(int charIndex, const CopyRange& copyRange, const quint8* o
10441044
const quint8* src = origBuffer + copyRange.offset;
10451045

10461046
while (count > 0) {
1047-
const auto lastByte = &_map[_mapSize.width() * _mapSize.height()];
1047+
const auto lastByte = _map.data() + _mapSize.width() * _mapSize.height();
10481048
int bytesToCopy = std::min((qint64)copyRange.blockSize, (qint64)(lastByte - dst));
10491049
if (bytesToCopy < 0)
10501050
break;

tests/unit_tests/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ set(CMAKE_CXX_STANDARD 17)
77
set(CMAKE_CXX_STANDARD_REQUIRED ON)
88

99
find_package(Qt6 REQUIRED COMPONENTS Core Gui Test Widgets Network)
10+
11+
# Fix macOS CI build failure due to AGL framework removal in macOS 14+ SDK
12+
if(APPLE)
13+
foreach(_target WrapOpenGL::WrapOpenGL Qt6::Gui Qt::Gui Qt6::Gui_private Qt::Gui_private)
14+
if(TARGET ${_target})
15+
get_target_property(_libs ${_target} INTERFACE_LINK_LIBRARIES)
16+
if(_libs)
17+
set(_new_libs "")
18+
set(_changed FALSE)
19+
foreach(_lib ${_libs})
20+
if(_lib MATCHES "AGL" OR _lib STREQUAL "AGL")
21+
set(_changed TRUE)
22+
else()
23+
list(APPEND _new_libs "${_lib}")
24+
endif()
25+
endforeach()
26+
if(_changed)
27+
set_target_properties(${_target} PROPERTIES INTERFACE_LINK_LIBRARIES "${_new_libs}")
28+
endif()
29+
endif()
30+
endif()
31+
endforeach()
32+
endif()
1033
set(CMAKE_AUTOMOC ON)
1134

1235
# We need to compile the sources from src/ but we cannot easily link against an executable target

0 commit comments

Comments
 (0)