Compare commits
110 Commits
nightly
...
releases/v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25e7ce5750 | ||
|
|
3b602eaaee | ||
|
|
954bee635e | ||
|
|
3d797b3c26 | ||
|
|
dfd8391382 | ||
|
|
5e09f4ec23 | ||
|
|
7daee7ca74 | ||
|
|
211e03ca66 | ||
|
|
9dc6879be3 | ||
|
|
1537e98d80 | ||
|
|
35e8c73f7c | ||
|
|
0c48aef5ee | ||
|
|
4a7544b9e7 | ||
|
|
87ebcff525 | ||
|
|
f0f6a22391 | ||
|
|
f76ea2a677 | ||
|
|
7a8c57a9a0 | ||
|
|
831f7e75ce | ||
|
|
a20f165421 | ||
|
|
5fa5bef467 | ||
|
|
db401ddf8e | ||
|
|
2e0cbd7285 | ||
|
|
bcfc9249d5 | ||
|
|
c74c123e44 | ||
|
|
38a59aff20 | ||
|
|
214c00ace9 | ||
|
|
0b5ab0bb1e | ||
|
|
49abdf1b10 | ||
|
|
c51f68d0fb | ||
|
|
b55e71e0a6 | ||
|
|
f2e7d25429 | ||
|
|
0a194d5893 | ||
|
|
246ad5d80d | ||
|
|
34bc55a648 | ||
|
|
76cf877115 | ||
|
|
8e4ccef52f | ||
|
|
b78a1024c1 | ||
|
|
fbae871d65 | ||
|
|
1a9fa0875b | ||
|
|
96232c2d80 | ||
|
|
6405c75242 | ||
|
|
5a853569e6 | ||
|
|
ea9d965ffe | ||
|
|
8b84c47b73 | ||
|
|
a3cd6e6a40 | ||
|
|
2f707afa67 | ||
|
|
765c8f4fe2 | ||
|
|
4120e10a95 | ||
|
|
67ec26b22a | ||
|
|
937ca4a327 | ||
|
|
96587415f6 | ||
|
|
b2f062cf10 | ||
|
|
91ef40ec99 | ||
|
|
684a9b3009 | ||
|
|
51d773cf14 | ||
|
|
cae063985a | ||
|
|
798bd25202 | ||
|
|
11df253fd3 | ||
|
|
a44278b1fe | ||
|
|
cd7705664d | ||
|
|
23e484c468 | ||
|
|
c4c8c46c11 | ||
|
|
f633c3f33a | ||
|
|
b8bcb815c8 | ||
|
|
81826df897 | ||
|
|
f6b2251205 | ||
|
|
1a7fefbc22 | ||
|
|
fdc1434cc6 | ||
|
|
230568f681 | ||
|
|
48c869fc89 | ||
|
|
4222904be9 | ||
|
|
20b4630faa | ||
|
|
6ddf2bb9fd | ||
|
|
77f049f0aa | ||
|
|
588412543c | ||
|
|
9939007fcf | ||
|
|
119f6f78b9 | ||
|
|
e2e397f188 | ||
|
|
60e2c32ae0 | ||
|
|
febd46ec58 | ||
|
|
bb9a0517fe | ||
|
|
e03d3d9f36 | ||
|
|
08daaec380 | ||
|
|
5a9f44e696 | ||
|
|
c95cbc5933 | ||
|
|
516a2f119e | ||
|
|
99e81b53af | ||
|
|
8bce2b072c | ||
|
|
539a00ae5d | ||
|
|
38075a1438 | ||
|
|
2c82d561c0 | ||
|
|
48e72a88c2 | ||
|
|
95c9168e25 | ||
|
|
64cbc16f78 | ||
|
|
b5f63e899c | ||
|
|
0a994d61b3 | ||
|
|
a8237326ad | ||
|
|
1253d68256 | ||
|
|
c944750f4d | ||
|
|
fb21f11554 | ||
|
|
d8e54e535b | ||
|
|
59afa06bf4 | ||
|
|
358f961f50 | ||
|
|
fc1b30eef2 | ||
|
|
596564ec48 | ||
|
|
a652b95816 | ||
|
|
0e3ce90db7 | ||
|
|
a3f31da365 | ||
|
|
27518cc584 | ||
|
|
3bcce0a243 |
137
.clang-tidy
@@ -1,69 +1,68 @@
|
||||
# Generated from CLion Inspection settings
|
||||
---
|
||||
Checks: '-*,
|
||||
mpi-*,
|
||||
bugprone-*,
|
||||
-bugprone-signal-handler,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-redundant-branch-condition,
|
||||
-bugprone-exception-escape,
|
||||
-bugprone-shared-ptr-array-mismatch,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-signed-char-misuse,
|
||||
-bugprone-unhandled-exception-at-new,
|
||||
-bugprone-infinite-loop,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
cert-err52-cpp,
|
||||
cert-err60-cpp,
|
||||
cert-err34-c,
|
||||
cert-str34-c,
|
||||
cert-dcl21-cpp,
|
||||
cert-msc50-cpp,
|
||||
cert-msc51-cpp,
|
||||
cert-dcl58-cpp,
|
||||
cert-flp30-c,
|
||||
cppcoreguidelines-avoid-const-or-ref-data-members,
|
||||
cppcoreguidelines-pro-type-member-init,
|
||||
cppcoreguidelines-slicing,
|
||||
cppcoreguidelines-interfaces-global-init,
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-narrowing-conversions,
|
||||
google-default-arguments,
|
||||
google-runtime-operator,
|
||||
google-explicit-constructor,
|
||||
hicpp-multiway-paths-covered,
|
||||
hicpp-exception-baseclass,
|
||||
misc-*,
|
||||
-misc-definitions-in-headers,
|
||||
-misc-unused-parameters,
|
||||
-misc-unused-alias-decls,
|
||||
-misc-use-anonymous-namespace,
|
||||
-misc-misleading-identifier,
|
||||
-misc-confusable-identifiers,
|
||||
-misc-misleading-bidirectional,
|
||||
-misc-static-assert,
|
||||
-misc-no-recursion,
|
||||
-misc-const-correctness,
|
||||
modernize-*,
|
||||
-modernize-use-trailing-return-type,
|
||||
openmp-use-default-none,
|
||||
performance-*,
|
||||
-performance-no-int-to-ptr,
|
||||
portability-*,
|
||||
-portability-restrict-system-includes,
|
||||
readability-*,
|
||||
-readability-redundant-preprocessor,
|
||||
-readability-named-parameter,
|
||||
-readability-function-size,
|
||||
-readability-use-anyofallof,
|
||||
-readability-identifier-length,
|
||||
-readability-magic-numbers,
|
||||
-readability-braces-around-statements,
|
||||
-readability-suspicious-call-argument,
|
||||
-readability-isolate-declaration,
|
||||
-readability-else-after-return,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-identifier-naming,
|
||||
*-include-cleaner,
|
||||
-readability-qualified-auto'
|
||||
Checks:
|
||||
- -*
|
||||
- mpi-*
|
||||
- bugprone-*
|
||||
- -bugprone-signal-handler
|
||||
- -bugprone-narrowing-conversions
|
||||
- -bugprone-redundant-branch-condition
|
||||
- -bugprone-exception-escape
|
||||
- -bugprone-shared-ptr-array-mismatch
|
||||
- -bugprone-implicit-widening-of-multiplication-result
|
||||
- -bugprone-signed-char-misuse
|
||||
- -bugprone-unhandled-exception-at-new
|
||||
- -bugprone-infinite-loop
|
||||
- -bugprone-easily-swappable-parameters
|
||||
- cert-err52-cpp
|
||||
- cert-err60-cpp
|
||||
- cert-err34-c
|
||||
- cert-str34-c
|
||||
- cert-dcl21-cpp
|
||||
- cert-msc50-cpp
|
||||
- cert-msc51-cpp
|
||||
- cert-dcl58-cpp
|
||||
- cert-flp30-c
|
||||
- cppcoreguidelines-avoid-const-or-ref-data-members
|
||||
- cppcoreguidelines-pro-type-member-init
|
||||
- cppcoreguidelines-slicing
|
||||
- cppcoreguidelines-interfaces-global-init
|
||||
- cppcoreguidelines-pro-type-static-cast-downcast
|
||||
- cppcoreguidelines-narrowing-conversions
|
||||
- google-default-arguments
|
||||
- google-runtime-operator
|
||||
- google-explicit-constructor
|
||||
- hicpp-multiway-paths-covered
|
||||
- hicpp-exception-baseclass
|
||||
- misc-*
|
||||
- -misc-definitions-in-headers
|
||||
- -misc-unused-parameters
|
||||
- -misc-unused-alias-decls
|
||||
- -misc-use-anonymous-namespace
|
||||
- -misc-misleading-identifier
|
||||
- -misc-confusable-identifiers
|
||||
- -misc-misleading-bidirectional
|
||||
- -misc-static-assert
|
||||
- -misc-no-recursion
|
||||
- -misc-const-correctness
|
||||
- modernize-*
|
||||
- -modernize-use-trailing-return-type
|
||||
- openmp-use-default-none
|
||||
- performance-*
|
||||
- -performance-no-int-to-ptr
|
||||
- portability-*
|
||||
- -portability-restrict-system-includes
|
||||
- readability-*
|
||||
- -readability-redundant-preprocessor
|
||||
- -readability-named-parameter
|
||||
- -readability-function-size
|
||||
- -readability-use-anyofallof
|
||||
- -readability-identifier-length
|
||||
- -readability-magic-numbers
|
||||
- -readability-braces-around-statements
|
||||
- -readability-suspicious-call-argument
|
||||
- -readability-isolate-declaration
|
||||
- -readability-else-after-return
|
||||
- -readability-redundant-access-specifiers
|
||||
- -readability-function-cognitive-complexity
|
||||
- -readability-identifier-naming
|
||||
- '*-include-cleaner'
|
||||
- -readability-qualified-auto
|
||||
|
||||
4
.github/FUNDING.yml
vendored
@@ -1,5 +1,5 @@
|
||||
# Sponsor links
|
||||
|
||||
patreon: werwolv
|
||||
custom: https://werwolv.net/donate
|
||||
github: WerWolv
|
||||
ko_fi: WerWolv
|
||||
custom: "https://werwolv.net/donate"
|
||||
|
||||
20
.github/workflows/build.yml
vendored
@@ -1,5 +1,9 @@
|
||||
name: Build
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -95,7 +99,6 @@ jobs:
|
||||
-DIMHEX_GENERATE_PDBS=ON \
|
||||
-DIMHEX_REPLACE_DWARF_WITH_PDB=ON \
|
||||
-DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" \
|
||||
-DCPACK_WIX_VERSION="4" \
|
||||
-DCPACK_WIX_ROOT="$(echo "$USERPROFILE" | tr '\\' '/')/.dotnet/tools" \
|
||||
..
|
||||
|
||||
@@ -166,6 +169,7 @@ jobs:
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-installer
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer ${{ matrix.architecture_name }}
|
||||
@@ -247,6 +251,7 @@ jobs:
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
cp dist/vcpkg.json vcpkg.json
|
||||
vcpkg install
|
||||
|
||||
- name: ⬇️ Install CMake and Ninja
|
||||
uses: lukka/get-cmake@latest
|
||||
@@ -279,7 +284,6 @@ jobs:
|
||||
-DIMHEX_COMMIT_HASH_LONG="$env:GITHUB_SHA" `
|
||||
-DIMHEX_COMMIT_BRANCH="$($env:GITHUB_REF -replace '.*/', '')" `
|
||||
-DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" `
|
||||
-DCPACK_WIX_VERSION="4" `
|
||||
-DCPACK_WIX_ROOT="$($env:USERPROFILE -replace '\\','/')/.dotnet/tools" `
|
||||
.
|
||||
|
||||
@@ -946,21 +950,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Fedora
|
||||
release_num: rawhide
|
||||
mock_config: fedora-rawhide
|
||||
- name: Fedora
|
||||
release_num: 43
|
||||
mock_config: fedora-43
|
||||
- name: Fedora
|
||||
release_num: 42
|
||||
mock_config: fedora-42
|
||||
- name: Fedora
|
||||
release_num: 41
|
||||
mock_config: fedora-41
|
||||
- name: RHEL-AlmaLinux
|
||||
release_num: 9
|
||||
mock_config: "alma+epel-9"
|
||||
|
||||
name: 🐧 ${{ matrix.name }} ${{ matrix.release_num }}
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
47
.github/workflows/dl-cache.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# https://gist.github.com/iTrooz/d5bacca32c0974edc6c1ac3ad3ee82f3
|
||||
# See https://github.com/cli/cli/issues/9125
|
||||
# Extract archive with `tar -xf cache.tzst --transform 's@\.\./@#@g' -P` to avoid ../ errors
|
||||
name: Download cache key
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
cache_key:
|
||||
description: 'Cache key'
|
||||
required: true
|
||||
type: string
|
||||
jobs:
|
||||
cache-download:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Query cache version
|
||||
id: version
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
VERSION=$(gh api repos/$GITHUB_REPOSITORY/actions/caches \
|
||||
--jq "
|
||||
.actions_caches[]
|
||||
| select(.ref == \"refs/heads/$GITHUB_REF_NAME\")
|
||||
| select(.key == \"${{ github.event.inputs.cache_key }}\")
|
||||
| .version
|
||||
")
|
||||
echo "version=$VERSION" | tee $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore cache
|
||||
uses: iTrooz/cache/restore@restore_with_version
|
||||
with:
|
||||
# Path won't be actually used, we will match by 'version'.
|
||||
path: .
|
||||
key: ${{ github.event.inputs.cache_key }}
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
|
||||
- name: Upload cached folder as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cache-artifact
|
||||
path: |
|
||||
/home/runner/work/**/*.tzst
|
||||
37
.github/workflows/nightly_release.yml
vendored
@@ -82,6 +82,43 @@ jobs:
|
||||
git fetch --tags --recurse-submodules=no
|
||||
git log nightly..origin/master --oneline --no-merges --pretty=format:'* %s' >> changelog.md
|
||||
|
||||
- name: ⬆️ Upload Unsigned x86_64 Windows Installer
|
||||
if: false
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-installer-x86_64
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer ${{ matrix.architecture_name }}
|
||||
path: |
|
||||
imhex-*-x86_64.msi
|
||||
|
||||
- name: ⬆️ Upload Unsigned ARM64 Windows Installer
|
||||
if: false
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-installer-arm64
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer ${{ matrix.architecture_name }}
|
||||
path: |
|
||||
imhex-*-arm64.msi
|
||||
|
||||
- name: 🗑️ Delete unsigned installers
|
||||
if: false
|
||||
run: |
|
||||
rm imhex-*.msi
|
||||
|
||||
- name: 🗝️ Sign Installer
|
||||
if: false
|
||||
uses: signpath/github-action-submit-signing-request@v1
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: 'f605a0e8-86cd-411c-bb6f-e05025afcc33'
|
||||
project-slug: 'ImHex'
|
||||
signing-policy-slug: 'release-signing'
|
||||
github-artifact-id: '${{ steps.upload-installer.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: '.'
|
||||
|
||||
- name: 📦 Update Pre-Release
|
||||
if: ${{ steps.check_commits.outputs.should_run == 'true' }}
|
||||
run: |
|
||||
|
||||
102
.github/workflows/release.yml
vendored
@@ -7,6 +7,12 @@ on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
commit_hash:
|
||||
type: string
|
||||
description: 'The commit hash to build (defaults to the latest commit on the default branch)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
release-update-repos:
|
||||
@@ -25,7 +31,7 @@ jobs:
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
if [ "$project_version" != "$tag_version" ]; then
|
||||
if [ "$project_version" != "$tag_version" ] && [ ! -z "$tag_version" ]; then
|
||||
echo "::warning::$project_version and $tag_version are not the same ! Refusing to populate release"
|
||||
exit 1
|
||||
fi
|
||||
@@ -41,6 +47,7 @@ jobs:
|
||||
tag: ImHex-v${{ env.IMHEX_VERSION }}
|
||||
repo: PatternLanguage
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
skipIfReleaseExists: true
|
||||
|
||||
- name: 🎫 Create ImHex-Patterns release
|
||||
uses: ncipollo/release-action@v1
|
||||
@@ -51,6 +58,7 @@ jobs:
|
||||
tag: ImHex-v${{ env.IMHEX_VERSION }}
|
||||
repo: ImHex-Patterns
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
skipIfReleaseExists: true
|
||||
|
||||
- name: 🎫 Create imhex-download-sdk release
|
||||
uses: ncipollo/release-action@v1
|
||||
@@ -61,11 +69,13 @@ jobs:
|
||||
tag: v${{ env.IMHEX_VERSION }}
|
||||
repo: imhex-download-sdk
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
skipIfReleaseExists: true
|
||||
|
||||
release-upload-artifacts:
|
||||
runs-on: ubuntu-24.04
|
||||
name: Release Upload Artifacts
|
||||
|
||||
outputs:
|
||||
IMHEX_VERSION: ${{ steps.verify_version.outputs.IMHEX_VERSION }}
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -74,17 +84,19 @@ jobs:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Verify version and set version variable
|
||||
id: verify_version
|
||||
run: |
|
||||
set -x
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
if [ "$project_version" != "$tag_version" ]; then
|
||||
if [ "$project_version" != "$tag_version" ] && [ ! -z "$tag_version" ]; then
|
||||
echo "::warning::$project_version and $tag_version are not the same ! Refusing to populate release"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "IMHEX_VERSION=$project_version" >> $GITHUB_ENV
|
||||
echo "IMHEX_VERSION=$project_version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: 🗜️ Create tarball from sources with dependencies
|
||||
run: tar --exclude-vcs -czvf Full.Sources.tar.gz ImHex
|
||||
@@ -97,6 +109,7 @@ jobs:
|
||||
branch: ${{ github.event.release.target_commitish }}
|
||||
workflow_conclusion: success
|
||||
skip_unpack: true
|
||||
commit: ${{ github.event.inputs.commit_hash }}
|
||||
|
||||
- name: 🗜️ Unzip files when needed
|
||||
run: |
|
||||
@@ -115,25 +128,87 @@ jobs:
|
||||
|
||||
- name: 🟩 Rename artifacts when needed
|
||||
run: |
|
||||
mv "Windows Portable x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-x86_64.zip
|
||||
mv "Windows Portable arm64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-arm64.zip
|
||||
mv "Windows Portable NoGPU x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-NoGPU-x86_64.zip
|
||||
mv "ImHex Web.zip" imhex-${{ env.IMHEX_VERSION }}-Web.zip
|
||||
mv "Windows Portable x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-x86_64.zip || true
|
||||
mv "Windows Portable arm64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-arm64.zip || true
|
||||
mv "Windows Portable NoGPU x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-NoGPU-x86_64.zip || true
|
||||
mv "ImHex Web.zip" imhex-${{ env.IMHEX_VERSION }}-Web.zip || true
|
||||
rm artifact.tar || true
|
||||
|
||||
- name: ⬆️ Upload Unsigned x86_64 Windows Installer
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-installer-x86_64
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer x86_64
|
||||
path: |
|
||||
imhex-*-x86_64.msi
|
||||
|
||||
- name: ⬆️ Upload Unsigned ARM64 Windows Installer
|
||||
if: false
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-installer-arm64
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer ARM64
|
||||
path: |
|
||||
imhex-*-arm64.msi
|
||||
|
||||
- name: 🗑️ Delete unsigned installers
|
||||
run: |
|
||||
rm imhex-*-x86_64.msi
|
||||
|
||||
- name: 🗝️ Sign x86_64 Installer
|
||||
uses: signpath/github-action-submit-signing-request@v1
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: 'f605a0e8-86cd-411c-bb6f-e05025afcc33'
|
||||
project-slug: 'ImHex'
|
||||
signing-policy-slug: 'release-signing'
|
||||
github-artifact-id: '${{ steps.upload-installer-x86_64.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: '.'
|
||||
|
||||
- name: 🗝️ Sign ARM64 Installer
|
||||
if: false
|
||||
uses: signpath/github-action-submit-signing-request@v1
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: 'f605a0e8-86cd-411c-bb6f-e05025afcc33'
|
||||
project-slug: 'ImHex'
|
||||
signing-policy-slug: 'release-signing'
|
||||
github-artifact-id: '${{ steps.upload-installer-arm64.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: '.'
|
||||
|
||||
- name: ⬆️ Upload everything to release
|
||||
uses: softprops/action-gh-release@4634c16e79c963813287e889244c50009e7f0981
|
||||
with:
|
||||
files: '*'
|
||||
|
||||
release-update-aur:
|
||||
name: Release update AUR package
|
||||
needs: release-upload-artifacts
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: ImHex
|
||||
|
||||
- name: ⬇️ Download artifacts
|
||||
run: |
|
||||
tagname=${GITHUB_REF#refs/tags/}
|
||||
version=${tagname#v}
|
||||
wget https://github.com/WerWolv/ImHex/releases/download/${tagname}/imhex-${version}-ArchLinux-x86_64.pkg.tar.zst
|
||||
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
set -x
|
||||
cp ImHex/dist/Arch/PKGBUILD .
|
||||
|
||||
hash=`md5sum imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst | cut -d ' ' -f 1`
|
||||
hash=`md5sum imhex-${{ needs.release-upload-artifacts.outputs.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst | cut -d ' ' -f 1`
|
||||
|
||||
sed -i 's/%version%/${{ env.IMHEX_VERSION }}/g' PKGBUILD
|
||||
sed -i 's/%version%/${{ needs.release-upload-artifacts.outputs.IMHEX_VERSION }}/g' PKGBUILD
|
||||
sed -i "s/(SKIP)/($hash)/g" PKGBUILD
|
||||
|
||||
- name: ⬆️ Publish AUR package
|
||||
@@ -147,9 +222,9 @@ jobs:
|
||||
pkgname: imhex-bin
|
||||
pkgbuild: ./PKGBUILD
|
||||
commit_username: iTrooz
|
||||
commit_email: itrooz@protonmail.com
|
||||
commit_email: hey@itrooz.fr
|
||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
commit_message: Bump to version ${{ env.IMHEX_VERSION }}
|
||||
commit_message: Bump to version ${{ needs.release-upload-artifacts.outputs.IMHEX_VERSION }}
|
||||
ssh_keyscan_types: rsa,ecdsa,ed25519
|
||||
|
||||
release-update-winget:
|
||||
@@ -161,6 +236,7 @@ jobs:
|
||||
shell: pwsh
|
||||
run: |
|
||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
|
||||
- name: ⬆️ Update winget manifest
|
||||
shell: pwsh
|
||||
env:
|
||||
@@ -193,7 +269,7 @@ jobs:
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_LOGIN }}
|
||||
with:
|
||||
snap: imhex-${{ env.IMHEX_VERSION }}-x86_64.snap
|
||||
snap: imhex-${{ needs.release-upload-artifacts.outputs.IMHEX_VERSION }}-x86_64.snap
|
||||
release: stable
|
||||
|
||||
- name: ⬆️ Publish arm64 Snap package
|
||||
@@ -202,5 +278,5 @@ jobs:
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_LOGIN }}
|
||||
with:
|
||||
snap: imhex-${{ env.IMHEX_VERSION }}-arm64.snap
|
||||
snap: imhex-${{ needs.release-upload-artifacts.outputs.IMHEX_VERSION }}-arm64.snap
|
||||
release: stable
|
||||
@@ -1,33 +1,38 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
# Options
|
||||
option(IMHEX_PLUGINS_IN_SHARE "Put the plugins in share/imhex/plugins instead of lib[..]/imhex/plugins (Linux only)" OFF)
|
||||
## General
|
||||
option(IMHEX_STRIP_RELEASE "Strip the release builds" ON )
|
||||
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
|
||||
option(IMHEX_IGNORE_BAD_CLONE "Disable the bad clone prevention checks" OFF)
|
||||
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
|
||||
option(IMHEX_IGNORE_BAD_COMPILER "Allow compiling with an unsupported compiler" OFF)
|
||||
option(IMHEX_USE_GTK_FILE_PICKER "Use GTK file picker instead of xdg-desktop-portals (Linux only)" OFF)
|
||||
option(IMHEX_DISABLE_STACKTRACE "Disables support for printing stack traces" OFF)
|
||||
option(IMHEX_BUNDLE_DOTNET "Bundle .NET runtime" ON )
|
||||
option(IMHEX_ENABLE_LTO "Enables Link Time Optimizations if possible" OFF)
|
||||
option(IMHEX_USE_DEFAULT_BUILD_SETTINGS "Use default build settings" OFF)
|
||||
option(IMHEX_STRICT_WARNINGS "Enable most available warnings and treat them as errors" ON )
|
||||
option(IMHEX_BUILD_HARDENING "Enable hardening flags for build" ON )
|
||||
option(IMHEX_STATIC_LINK_PLUGINS "Statically link all plugins into the main executable" OFF)
|
||||
option(IMHEX_GENERATE_PACKAGE "Specify if a native package should be built. (Windows and MacOS only)" OFF)
|
||||
option(IMHEX_ENABLE_UNITY_BUILD "Enables building ImHex as a unity build." OFF)
|
||||
option(IMHEX_GENERATE_PDBS "Enable generating PDB files in non-debug builds (Windows only)" OFF)
|
||||
option(IMHEX_REPLACE_DWARF_WITH_PDB "Remove DWARF information from binaries when generating PDBS (Windows only)" OFF)
|
||||
option(IMHEX_ENABLE_STD_ASSERTS "Enable debug asserts in the C++ std library. (Breaks Plugin ABI!)" OFF)
|
||||
option(IMHEX_ENABLE_UNIT_TESTS "Enable building unit tests" ON )
|
||||
option(IMHEX_ENABLE_PLUGIN_TESTS "Enable building plugin tests" ON )
|
||||
option(IMHEX_ENABLE_IMGUI_TEST_ENGINE "Enable the ImGui Test Engine" OFF)
|
||||
option(IMHEX_ENABLE_PRECOMPILED_HEADERS "Enable precompiled headers" OFF)
|
||||
option(IMHEX_COMPRESS_DEBUG_INFO "Compress debug information" ON )
|
||||
option(IMHEX_ENABLE_CXX_MODULES "Enable C++20 Module compilation. Testing only!" OFF)
|
||||
option(IMHEX_ENABLE_CPPCHECK "Enable cppcheck static analysis" OFF)
|
||||
option(IMHEX_BUNDLE_PLUGIN_SDK "Enable bundling of Plugin SDK into install package" ON )
|
||||
## Testing
|
||||
option(IMHEX_ENABLE_UNIT_TESTS "Enable building unit tests" ON )
|
||||
option(IMHEX_ENABLE_IMGUI_TEST_ENGINE "Enable the ImGui Test Engine" OFF)
|
||||
option(IMHEX_ENABLE_STD_ASSERTS "Enable debug asserts in the C++ std library. (Breaks Plugin ABI!)" OFF)
|
||||
## Debug info
|
||||
option(IMHEX_COMPRESS_DEBUG_INFO "Compress debug information" ON )
|
||||
option(IMHEX_GENERATE_PDBS "Enable generating PDB files in non-debug builds (Windows only)" OFF)
|
||||
option(IMHEX_REPLACE_DWARF_WITH_PDB "Remove DWARF information from binaries when generating PDBS (Windows only)" OFF)
|
||||
option(IMHEX_STRICT_WARNINGS "Enable most available warnings and treat them as errors" ON )
|
||||
option(IMHEX_DISABLE_STACKTRACE "Disables support for printing stack traces" OFF)
|
||||
## Plugins
|
||||
option(IMHEX_STATIC_LINK_PLUGINS "Statically link all plugins into the main executable" OFF)
|
||||
option(IMHEX_ENABLE_PLUGIN_TESTS "Enable building plugin tests" ON )
|
||||
option(IMHEX_INCLUDE_PLUGINS "Semicolon-separated list of plugins to include in the build (empty = build all)" "" )
|
||||
option(IMHEX_EXCLUDE_PLUGINS "Semicolon-separated list of plugins to exclude from the build" "" )
|
||||
|
||||
set(IMHEX_BASE_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(CMAKE_MODULE_PATH "${IMHEX_BASE_FOLDER}/cmake/modules")
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
|
||||
## Supporting
|
||||
|
||||
If you like my work, please consider supporting me on GitHub Sponsors, Patreon or PayPal. Thanks a lot!
|
||||
If you like my work, please consider supporting me on GitHub Sponsors, Ko-Fi or PayPal. Thanks a lot!
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/sponsors/WerWolv"><img src="https://werwolv.net/assets/github_banner.png" alt="GitHub donate button" /></a>
|
||||
<a href="https://www.patreon.com/werwolv"><img src="https://c5.patreon.com/external/logo/become_a_patron_button.png" alt="Patreon donate button" /></a>
|
||||
<a href="https://ko-fi.com/WerWolv"><img src="https://werwolv.net/assets/kofi_banner.png" alt="Ko-Fi donate button" /></a>
|
||||
<a href="https://werwolv.net/donate"><img src="https://werwolv.net/assets/paypal_banner.png" alt="PayPal donate button" /></a>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -175,15 +175,11 @@ macro(detectOS)
|
||||
endif()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(IMHEX_PLUGINS_IN_SHARE)
|
||||
set(PLUGINS_INSTALL_LOCATION "share/imhex/plugins")
|
||||
else()
|
||||
set(PLUGINS_INSTALL_LOCATION "${CMAKE_INSTALL_LIBDIR}/imhex/plugins")
|
||||
set(PLUGINS_INSTALL_LOCATION "${CMAKE_INSTALL_LIBDIR}/imhex/plugins")
|
||||
|
||||
# Add System plugin location for plugins to be loaded from
|
||||
# IMPORTANT: This does not work for Sandboxed or portable builds such as the Flatpak or AppImage release
|
||||
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex")
|
||||
endif()
|
||||
# Add System plugin location for plugins to be loaded from
|
||||
# IMPORTANT: This does not work for Sandboxed or portable builds such as the Flatpak or AppImage release
|
||||
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex")
|
||||
|
||||
else ()
|
||||
message(FATAL_ERROR "Unknown / unsupported system!")
|
||||
@@ -205,11 +201,14 @@ macro(configurePackingResources)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_PACKAGE_VENDOR "WerWolv")
|
||||
set(CPACK_WIX_VERSION 4)
|
||||
set(CPACK_WIX_UPGRADE_GUID "05000E99-9659-42FD-A1CF-05C554B39285")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/dist/windows/icon.ico")
|
||||
set(CPACK_WIX_UI_BANNER "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_banner.png")
|
||||
set(CPACK_WIX_UI_DIALOG "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_dialog.png")
|
||||
set(CPACK_WIX_CULTURES "en-US;de-DE;ja-JP;it-IT;pt-BR;zh-CN;zh-TW;ru-RU")
|
||||
set(CPACK_WIX_PATCH_FILE "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_patch.xml")
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ImHex")
|
||||
set_property(INSTALL "$<TARGET_FILE_NAME:main>"
|
||||
PROPERTY CPACK_START_MENU_SHORTCUTS "ImHex"
|
||||
@@ -312,7 +311,7 @@ macro(createPackage)
|
||||
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
|
||||
)
|
||||
|
||||
if(_c_deps_FILENAMES AND NOT _c_deps STREQUAL "")
|
||||
if(_c_deps_FILENAMES AND _c_deps AND NOT (_c_deps STREQUAL ""))
|
||||
message(WARNING "Conflicting dependencies for library: \"${_c_deps}\"!")
|
||||
endif()
|
||||
|
||||
@@ -560,6 +559,9 @@ function(detectBadClone)
|
||||
|
||||
file (GLOB EXTERNAL_DIRS "lib/external/*" "lib/third_party/*")
|
||||
foreach (EXTERNAL_DIR ${EXTERNAL_DIRS})
|
||||
if(NOT IS_DIRECTORY "${EXTERNAL_DIR}")
|
||||
continue()
|
||||
endif()
|
||||
file(GLOB_RECURSE RESULT "${EXTERNAL_DIR}/*")
|
||||
list(LENGTH RESULT ENTRY_COUNT)
|
||||
if(ENTRY_COUNT LESS_EQUAL 1)
|
||||
@@ -587,7 +589,9 @@ endfunction()
|
||||
macro(detectBundledPlugins)
|
||||
file(GLOB PLUGINS_DIRS "plugins/*")
|
||||
|
||||
if (NOT DEFINED IMHEX_INCLUDE_PLUGINS)
|
||||
if (IMHEX_INCLUDE_PLUGINS)
|
||||
set(PLUGINS ${IMHEX_INCLUDE_PLUGINS})
|
||||
else()
|
||||
foreach(PLUGIN_DIR ${PLUGINS_DIRS})
|
||||
if (EXISTS "${PLUGIN_DIR}/CMakeLists.txt")
|
||||
get_filename_component(PLUGIN_NAME ${PLUGIN_DIR} NAME)
|
||||
@@ -596,8 +600,6 @@ macro(detectBundledPlugins)
|
||||
endif ()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(PLUGINS ${IMHEX_INCLUDE_PLUGINS})
|
||||
endif()
|
||||
|
||||
foreach(PLUGIN_NAME ${PLUGINS})
|
||||
@@ -608,9 +610,13 @@ macro(detectBundledPlugins)
|
||||
message(FATAL_ERROR "No bundled plugins enabled")
|
||||
endif()
|
||||
|
||||
if (NOT ("builtin" IN_LIST PLUGINS))
|
||||
message(FATAL_ERROR "The 'builtin' plugin is required for ImHex to work!")
|
||||
endif ()
|
||||
set(REQUIRED_PLUGINS builtin fonts ui)
|
||||
foreach(PLUGIN ${REQUIRED_PLUGINS})
|
||||
list(FIND PLUGINS ${PLUGIN} PLUGIN_INDEX)
|
||||
if (PLUGIN_INDEX EQUAL -1)
|
||||
message(FATAL_ERROR "Required plugin '${PLUGIN}' is not enabled!")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(setVariableInParent variable value)
|
||||
|
||||
4
dist/AppImage/AppImageBuilder.yml
vendored
@@ -15,8 +15,8 @@ AppDir:
|
||||
- "{{ARCHITECTURE_PACKAGE}}"
|
||||
allow_unauthenticated: true
|
||||
sources:
|
||||
- sourceline: 'deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ noble main restricted universe multiverse'
|
||||
- sourceline: 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ noble main restricted universe multiverse'
|
||||
- sourceline: 'deb [arch=amd64] https://us.archive.ubuntu.com/ubuntu/ noble main restricted universe multiverse'
|
||||
- sourceline: 'deb [arch=arm64] https://ports.ubuntu.com/ubuntu-ports/ noble main restricted universe multiverse'
|
||||
include:
|
||||
- libgdk-pixbuf2.0-0
|
||||
- libgdk-pixbuf2.0-common
|
||||
|
||||
28
dist/AppImage/Dockerfile
vendored
@@ -30,9 +30,9 @@ ARG LTO=ON
|
||||
ARG BUILD_TYPE=RelWithDebInfo
|
||||
ARG GIT_COMMIT_HASH
|
||||
ARG GIT_BRANCH
|
||||
ARG ARCHITECTURE_PACKAGE
|
||||
ARG ARCHITECTURE_FILE_NAME
|
||||
ARG ARCHITECTURE_APPIMAGE_BUILDER
|
||||
ARG ARCHITECTURE_PACKAGE=x86_64
|
||||
ARG ARCHITECTURE_FILE_NAME=amd64
|
||||
ARG ARCHITECTURE_APPIMAGE_BUILDER=x86_64
|
||||
WORKDIR /build
|
||||
|
||||
# Ubuntu sh doesnt support string substitution
|
||||
@@ -42,16 +42,18 @@ RUN <<EOF
|
||||
# Prepare ImHex build
|
||||
set -xe
|
||||
|
||||
CC=gcc-14 CXX=g++-14 cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GIT_COMMIT_HASH}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${GIT_BRANCH}" \
|
||||
-DIMHEX_ENABLE_LTO=${LTO} \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
CC=gcc-14 CXX=g++-14 cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GIT_COMMIT_HASH}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${GIT_BRANCH}" \
|
||||
-DIMHEX_ENABLE_LTO=${LTO} \
|
||||
-DIMHEX_BUNDLE_PLUGIN_SDK=OFF \
|
||||
`# To prevent using a libdir with an architecture-specific name` \
|
||||
-DCMAKE_INSTALL_LIBDIR="lib" \
|
||||
/imhex
|
||||
EOF
|
||||
|
||||
|
||||
2
dist/DEBIAN/control.in
vendored
@@ -4,7 +4,7 @@ Section: editors
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
License: GNU GPL-2
|
||||
Depends: libfontconfig1, libglfw3 | libglfw3-wayland, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal, libssh2-1, md4c
|
||||
Depends: libfontconfig1, libglfw3 | libglfw3-wayland, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal, libssh2-1, libmd4c0
|
||||
Maintainer: WerWolv <hey@werwolv.net>
|
||||
Description: ImHex Hex Editor
|
||||
A Hex Editor for Reverse Engineers, Programmers and
|
||||
|
||||
1
dist/flatpak/net.werwolv.ImHex.yaml
vendored
@@ -120,6 +120,7 @@ modules:
|
||||
- -DUSE_SYSTEM_FMT=ON
|
||||
- -DUSE_SYSTEM_YARA=ON
|
||||
- -DIMHEX_OFFLINE_BUILD=ON
|
||||
- -DIMHEX_BUNDLE_PLUGIN_SDK=OFF
|
||||
- -DCMAKE_INSTALL_LIBDIR=lib
|
||||
- -DCMAKE_INSTALL_RPATH='$ORIGIN/../lib:$ORIGIN/../lib64'
|
||||
sources:
|
||||
|
||||
2
dist/macOS/0001-glfw-SW.patch
vendored
@@ -1,5 +1,5 @@
|
||||
From 9c8665af4c2e2ce66555c15c05c72027bfdf0cb6 Mon Sep 17 00:00:00 2001
|
||||
From: iTrooz <itrooz@protonmail.com>
|
||||
From: iTrooz <hey@itrooz.fr>
|
||||
Date: Mon, 29 Aug 2022 17:29:38 +0200
|
||||
Subject: [PATCH] Use software rendering on MacOS
|
||||
|
||||
|
||||
4
dist/macOS/arm64.Dockerfile
vendored
@@ -150,9 +150,7 @@ EOF
|
||||
# Build ImHex
|
||||
## Copy ImHex
|
||||
COPY --from=imhex / /mnt/ImHex
|
||||
## Patch ImHex with hacks
|
||||
# COPY toolchain.cmake.2 /osxcross/target/toolchain.cmake
|
||||
# Configure ImHex build
|
||||
## Configure ImHex build
|
||||
RUN --mount=type=cache,target=/cache --mount=type=cache,target=/mnt/ImHex/build/_deps \
|
||||
cd /mnt/ImHex && \
|
||||
# compilers
|
||||
|
||||
1
dist/snap/snapcraft.yaml
vendored
@@ -41,6 +41,7 @@ parts:
|
||||
- -DCMAKE_C_COMPILER_LAUNCHER=${CCACHE}
|
||||
- -DCMAKE_CXX_COMPILER_LAUNCHER=${CCACHE}
|
||||
- -DIMHEX_PATTERNS_PULL_MASTER=ON
|
||||
- -DIMHEX_BUNDLE_PLUGIN_SDK=OFF
|
||||
cmake-generator: Ninja
|
||||
build-packages:
|
||||
- cmake
|
||||
|
||||
12
dist/web/Dockerfile
vendored
@@ -2,7 +2,7 @@ FROM emscripten/emsdk:4.0.21 AS build
|
||||
|
||||
# Used to invalidate layer cache but not mount cache
|
||||
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
|
||||
ARG UNIQUEKEY 1
|
||||
ARG UNIQUEKEY=1
|
||||
|
||||
RUN apt update
|
||||
RUN apt install -y git ccache autoconf automake libtool pkg-config ninja-build
|
||||
@@ -12,13 +12,13 @@ RUN <<EOF
|
||||
# Note: we are a patch on the libmagic port
|
||||
set -xe
|
||||
|
||||
git clone https://github.com/microsoft/vcpkg /vcpkg
|
||||
git -C /vcpkg pull
|
||||
git clone --depth 1 https://github.com/microsoft/vcpkg /vcpkg
|
||||
/vcpkg/bootstrap-vcpkg.sh
|
||||
sed -i 's/vcpkg_install_make(${EXTRA_ARGS})/vcpkg_install_make(${EXTRA_ARGS} SUBPATH src)/g' /vcpkg/ports/libmagic/portfile.cmake
|
||||
EOF
|
||||
|
||||
# Patch vcpkg build instructions to add -pthread
|
||||
# Patch vcpkg build instructions to add -pthread flag
|
||||
# Even dependencies must be built with -pthread to be able to use USE_PTHREADS=1
|
||||
RUN <<EOF
|
||||
set -xe
|
||||
|
||||
@@ -50,6 +50,7 @@ ENV CCACHE_DIR=/cache/ccache
|
||||
|
||||
RUN mkdir /build
|
||||
WORKDIR /build
|
||||
ARG BUILD_TYPE=Release
|
||||
RUN --mount=type=cache,target=/cache \
|
||||
--mount=type=bind,source=.,target=/imhex <<EOF
|
||||
|
||||
@@ -70,7 +71,7 @@ ccache -zs
|
||||
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
|
||||
-DLIBROMFS_COMPRESS_RESOURCES=OFF \
|
||||
-DIMHEX_ENABLE_PLUGIN_TESTS=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||
|
||||
ninja -j $JOBS
|
||||
|
||||
@@ -106,3 +107,4 @@ COPY --from=build [ \
|
||||
|
||||
FROM nginx
|
||||
COPY --from=raw . /usr/share/nginx/html
|
||||
RUN chmod -R 755 /usr/share/nginx/html
|
||||
|
||||
1
dist/web/compose.yml
vendored
@@ -1,5 +1,4 @@
|
||||
# docker compose -f dist/web/compose.yml up --build
|
||||
version: '3'
|
||||
services:
|
||||
imhex_web:
|
||||
image: imhex_web:latest
|
||||
|
||||
18
dist/web/source/wasm-config.js
vendored
@@ -59,8 +59,14 @@ monkeyPatch((file, done) => {
|
||||
const mibTotal = (wasmSize / 1024**2).toFixed(1);
|
||||
|
||||
let root = document.querySelector(':root');
|
||||
root.style.setProperty("--progress", `${percent}%`)
|
||||
document.getElementById("progress-bar-content").innerHTML = `${percent}% [${mibNow} MiB / ${mibTotal} MiB]`;
|
||||
if (root != null) {
|
||||
root.style.setProperty("--progress", `${percent}%`)
|
||||
let progressBar = document.getElementById("progress-bar-content");
|
||||
|
||||
if (progressBar != null) {
|
||||
progressBar.innerHTML = `${percent}% [${mibNow} MiB / ${mibTotal} MiB]`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function glfwSetCursorCustom(wnd, shape) {
|
||||
@@ -174,7 +180,9 @@ var Module = {
|
||||
},
|
||||
onRuntimeInitialized: function() {
|
||||
// Triggered when the wasm module is loaded and ready to use.
|
||||
document.getElementById("loading").style.display = "none"
|
||||
let loading = document.getElementById("loading");
|
||||
if (loading != null)
|
||||
document.getElementById("loading").style.display = "none"
|
||||
document.getElementById("canvas").style.display = "initial"
|
||||
|
||||
clearTimeout(notWorkingTimer);
|
||||
@@ -263,8 +271,8 @@ function js_resizeCanvas() {
|
||||
|
||||
canvas.top = document.documentElement.clientTop;
|
||||
canvas.left = document.documentElement.clientLeft;
|
||||
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 0);
|
||||
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 0) * window.devicePixelRatio;
|
||||
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 0) * window.devicePixelRatio;
|
||||
}
|
||||
|
||||
// Prevent some default browser shortcuts from preventing ImHex ones to work
|
||||
|
||||
2
lib/external/libwolv
vendored
2
lib/external/pattern_language
vendored
@@ -145,62 +145,17 @@ EXPORT_MODULE namespace hex {
|
||||
* @brief Returns the icon of the achievement
|
||||
* @return Icon of the achievement
|
||||
*/
|
||||
[[nodiscard]] const ImGuiExt::Texture &getIcon() const {
|
||||
if (m_iconData.empty())
|
||||
return m_icon;
|
||||
|
||||
if (m_icon.isValid())
|
||||
return m_icon;
|
||||
|
||||
m_icon = ImGuiExt::Texture::fromImage(m_iconData.data(), m_iconData.size(), ImGuiExt::Texture::Filter::Linear);
|
||||
|
||||
return m_icon;
|
||||
[[nodiscard]] const char* getIcon() const {
|
||||
return m_icon.c_str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @param icon Icon glyph
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const std::byte> data) {
|
||||
m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const u8> data) {
|
||||
m_iconData.assign(data.begin(), data.end());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::vector<u8> data) {
|
||||
m_iconData = std::move(data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(const std::vector<std::byte> &data) {
|
||||
m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
Achievement& setIcon(std::string icon) {
|
||||
m_icon = std::move(icon);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -284,8 +239,7 @@ EXPORT_MODULE namespace hex {
|
||||
|
||||
std::function<void(Achievement &)> m_clickCallback;
|
||||
|
||||
std::vector<u8> m_iconData;
|
||||
mutable ImGuiExt::Texture m_icon;
|
||||
std::string m_icon;
|
||||
|
||||
u32 m_progress = 0;
|
||||
u32 m_maxProgress = 1;
|
||||
|
||||
@@ -19,7 +19,7 @@ EXPORT_MODULE namespace hex {
|
||||
|
||||
void addProviderName(const UnlocalizedString &unlocalizedName, const char *icon);
|
||||
|
||||
using ProviderCreationFunction = std::function<std::unique_ptr<prv::Provider>()>;
|
||||
using ProviderCreationFunction = std::function<std::shared_ptr<prv::Provider>()>;
|
||||
void add(const std::string &typeName, ProviderCreationFunction creationFunction);
|
||||
|
||||
struct Entry {
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace hex {
|
||||
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
|
||||
* (although the event can also be called manually without problem)
|
||||
*/
|
||||
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
||||
EVENT_DEF(EventProviderCreated, std::shared_ptr<prv::Provider>);
|
||||
|
||||
/**
|
||||
* @brief Called as a continuation of EventProviderCreated
|
||||
|
||||
@@ -8,7 +8,12 @@ namespace hex {
|
||||
/**
|
||||
* @brief Creates a provider from its unlocalized name, and add it to the provider list
|
||||
*/
|
||||
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
|
||||
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, std::shared_ptr<hex::prv::Provider> *);
|
||||
|
||||
/**
|
||||
* @brief Used internally when opening a provider through the API
|
||||
*/
|
||||
EVENT_DEF(RequestOpenProvider, std::shared_ptr<prv::Provider>);
|
||||
|
||||
/**
|
||||
* @brief Move the data from all PerProvider instances from one provider to another
|
||||
|
||||
@@ -86,7 +86,7 @@ EXPORT_MODULE namespace hex {
|
||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||
* @param select Whether to select the provider after adding it
|
||||
*/
|
||||
void add(std::unique_ptr<prv::Provider> &&provider, bool skipLoadInterface = false, bool select = true);
|
||||
void add(std::shared_ptr<prv::Provider> &&provider, bool skipLoadInterface = false, bool select = true);
|
||||
|
||||
/**
|
||||
* @brief Creates a new provider and adds it to the list of providers
|
||||
@@ -111,12 +111,18 @@ EXPORT_MODULE namespace hex {
|
||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||
* @param select Whether to select the provider after adding it
|
||||
*/
|
||||
prv::Provider* createProvider(
|
||||
std::shared_ptr<prv::Provider> createProvider(
|
||||
const UnlocalizedString &unlocalizedName,
|
||||
bool skipLoadInterface = false,
|
||||
bool select = true
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Opens a provider, making its data available to ImHex and handling any error that may occur
|
||||
* @param provider The provider to open
|
||||
*/
|
||||
void openProvider(std::shared_ptr<prv::Provider> provider);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <condition_variable>
|
||||
#include <source_location>
|
||||
#include <thread>
|
||||
#include <hex/trace/exceptions.hpp>
|
||||
|
||||
EXPORT_MODULE namespace hex {
|
||||
|
||||
@@ -94,7 +95,12 @@ EXPORT_MODULE namespace hex {
|
||||
std::atomic_flag m_hadException;
|
||||
std::string m_exceptionMessage;
|
||||
|
||||
struct TaskInterruptor { virtual ~TaskInterruptor() = default; };
|
||||
struct TaskInterruptor {
|
||||
TaskInterruptor() {
|
||||
trace::disableExceptionCaptureForCurrentThread();
|
||||
}
|
||||
virtual ~TaskInterruptor() = default;
|
||||
};
|
||||
|
||||
friend class TaskHolder;
|
||||
friend class TaskManager;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/imhex_api/system.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -9,6 +10,9 @@ namespace hex {
|
||||
class AutoResetBase {
|
||||
public:
|
||||
virtual ~AutoResetBase() = default;
|
||||
|
||||
private:
|
||||
friend void ImHexApi::System::impl::cleanup();
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
@@ -19,16 +23,20 @@ namespace hex {
|
||||
public:
|
||||
using Type = T;
|
||||
|
||||
AutoReset() {
|
||||
ImHexApi::System::impl::addAutoResetObject(this);
|
||||
AutoReset() noexcept {
|
||||
try {
|
||||
ImHexApi::System::impl::addAutoResetObject(this);
|
||||
} catch (std::exception &e) {
|
||||
log::error("Failed to register AutoReset object: {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
AutoReset(const T &value) : AutoReset() {
|
||||
explicit(false) AutoReset(const T &value) : AutoReset() {
|
||||
m_value = value;
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
AutoReset(T &&value) noexcept : AutoReset() {
|
||||
explicit(false) AutoReset(T &&value) noexcept : AutoReset() {
|
||||
m_value = std::move(value);
|
||||
m_valid = true;
|
||||
}
|
||||
@@ -61,25 +69,23 @@ namespace hex {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
T& operator=(const T &value) {
|
||||
AutoReset& operator=(const T &value) {
|
||||
m_value = value;
|
||||
m_valid = true;
|
||||
return m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator=(T &&value) noexcept {
|
||||
AutoReset& operator=(T &&value) noexcept {
|
||||
m_value = std::move(value);
|
||||
m_valid = true;
|
||||
return m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
[[nodiscard]] bool isValid() const {
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
private:
|
||||
friend void ImHexApi::System::impl::cleanup();
|
||||
|
||||
void reset() override {
|
||||
if constexpr (requires { m_value.reset(); }) {
|
||||
m_value.reset();
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
static_assert(false, "Debug variables are only intended for use during development.");
|
||||
#endif
|
||||
|
||||
namespace hex::trace {
|
||||
struct StackTraceResult;
|
||||
}
|
||||
|
||||
namespace hex::dbg {
|
||||
|
||||
namespace impl {
|
||||
@@ -47,4 +51,6 @@ namespace hex::dbg {
|
||||
bool debugModeEnabled();
|
||||
void setDebugModeEnabled(bool enabled);
|
||||
|
||||
void printStackTrace(const trace::StackTraceResult &stackTrace);
|
||||
|
||||
}
|
||||
@@ -98,6 +98,8 @@ namespace hex {
|
||||
|
||||
void startProgram(const std::vector<std::string> &command);
|
||||
int executeCommand(const std::string &command);
|
||||
std::optional<std::string> executeCommandWithOutput(const std::string &command);
|
||||
void executeCommandDetach(const std::string &command);
|
||||
void openWebpage(std::string url);
|
||||
|
||||
extern "C" void registerFont(const char *fontName, const char *fontPath);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace hex::prv {
|
||||
CachedProvider(size_t cacheBlockSize = 4096, size_t maxBlocks = 1024);
|
||||
~CachedProvider() override;
|
||||
|
||||
bool open() override;
|
||||
OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace hex::prv {
|
||||
[[nodiscard]] bool isSavable() const override { return m_name.empty(); }
|
||||
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
|
||||
@@ -79,6 +79,65 @@ namespace hex::prv {
|
||||
public:
|
||||
constexpr static u64 MaxPageSize = 0xFFFF'FFFF'FFFF'FFFF;
|
||||
|
||||
class OpenResult {
|
||||
public:
|
||||
OpenResult() : m_result(std::monostate{}) {}
|
||||
|
||||
[[nodiscard]] static OpenResult failure(std::string errorMessage) {
|
||||
OpenResult result;
|
||||
result.m_result = std::move(errorMessage);
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] static OpenResult warning(std::string warningMessage) {
|
||||
OpenResult result;
|
||||
result.m_result = std::move(warningMessage);
|
||||
result.m_warning = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] static OpenResult redirect(Provider *provider) {
|
||||
OpenResult result;
|
||||
result.m_result = provider;
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSuccess() const {
|
||||
return std::holds_alternative<std::monostate>(m_result);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isFailure() const {
|
||||
return std::holds_alternative<std::string>(m_result) && !m_warning;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isWarning() const {
|
||||
return std::holds_alternative<std::string>(m_result) && m_warning;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isRedirecting() const {
|
||||
return std::holds_alternative<Provider*>(m_result);
|
||||
}
|
||||
|
||||
[[nodiscard]] Provider* getRedirectProvider() const {
|
||||
if (std::holds_alternative<Provider*>(m_result)) {
|
||||
return std::get<Provider*>(m_result);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view getErrorMessage() const {
|
||||
if (std::holds_alternative<std::string>(m_result)) {
|
||||
return std::get<std::string>(m_result);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::variant<std::monostate, std::string, Provider*> m_result;
|
||||
bool m_warning = false;
|
||||
};
|
||||
|
||||
Provider();
|
||||
virtual ~Provider();
|
||||
Provider(const Provider&) = delete;
|
||||
@@ -94,7 +153,7 @@ namespace hex::prv {
|
||||
* @note This is not related to the EventProviderOpened event
|
||||
* @return true if the provider was opened successfully, else false
|
||||
*/
|
||||
[[nodiscard]] virtual bool open() = 0;
|
||||
[[nodiscard]] virtual OpenResult open() = 0;
|
||||
|
||||
/**
|
||||
* @brief Closes this provider
|
||||
@@ -262,9 +321,6 @@ namespace hex::prv {
|
||||
void skipLoadInterface() { m_skipLoadInterface = true; }
|
||||
[[nodiscard]] bool shouldSkipLoadInterface() const { return m_skipLoadInterface; }
|
||||
|
||||
void setErrorMessage(const std::string &errorMessage) { m_errorMessage = errorMessage; }
|
||||
[[nodiscard]] const std::string& getErrorMessage() const { return m_errorMessage; }
|
||||
|
||||
template<std::derived_from<undo::Operation> T>
|
||||
bool addUndoableOperation(auto && ... args) {
|
||||
return m_undoRedoStack.add<T>(std::forward<decltype(args)...>(args)...);
|
||||
@@ -296,8 +352,6 @@ namespace hex::prv {
|
||||
*/
|
||||
bool m_skipLoadInterface = false;
|
||||
|
||||
std::string m_errorMessage = "Unspecified error";
|
||||
|
||||
u64 m_pageSize = MaxPageSize;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace hex::test {
|
||||
|
||||
[[nodiscard]] UnlocalizedString getTypeName() const override { return "hex.test.provider.test"; }
|
||||
|
||||
bool open() override { return true; }
|
||||
OpenResult open() override { return {}; }
|
||||
void close() override { }
|
||||
|
||||
nlohmann::json storeSettings(nlohmann::json) const override { return {}; }
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -27,7 +26,7 @@ namespace hex {
|
||||
* @brief Draws the view
|
||||
* @note Do not override this method. Override drawContent() instead
|
||||
*/
|
||||
virtual void draw() = 0;
|
||||
virtual void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draws the content of the view
|
||||
@@ -126,6 +125,7 @@ namespace hex {
|
||||
class Window;
|
||||
class Special;
|
||||
class Floating;
|
||||
class Scrolling;
|
||||
class Modal;
|
||||
class FullScreen;
|
||||
|
||||
@@ -153,16 +153,10 @@ namespace hex {
|
||||
*/
|
||||
virtual void drawHelpText() = 0;
|
||||
|
||||
void draw() final {
|
||||
if (this->shouldDraw()) {
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
const auto title = fmt::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName()));
|
||||
if (ImGui::Begin(title.c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
|
||||
TutorialManager::setLastItemInteractiveHelpPopup([this]{ this->drawHelpText(); });
|
||||
this->drawContent();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) override;
|
||||
|
||||
virtual bool allowScroll() const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -174,12 +168,7 @@ namespace hex {
|
||||
public:
|
||||
explicit Special(UnlocalizedString unlocalizedName) : View(std::move(unlocalizedName), "") {}
|
||||
|
||||
void draw() final {
|
||||
if (this->shouldDraw()) {
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
this->drawContent();
|
||||
}
|
||||
}
|
||||
void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) final;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -189,7 +178,24 @@ namespace hex {
|
||||
public:
|
||||
explicit Floating(UnlocalizedString unlocalizedName, const char *icon) : Window(std::move(unlocalizedName), icon) {}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getWindowFlags() const override { return ImGuiWindowFlags_NoDocking; }
|
||||
void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) final;
|
||||
|
||||
[[nodiscard]] bool shouldStoreWindowState() const override { return false; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A view that draws all its content at once without any scrolling being done by the window itself
|
||||
*/
|
||||
class View::Scrolling : public View::Window {
|
||||
public:
|
||||
explicit Scrolling(UnlocalizedString unlocalizedName, const char *icon) : Window(std::move(unlocalizedName), icon) {}
|
||||
|
||||
void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) final;
|
||||
|
||||
bool allowScroll() const final {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool shouldStoreWindowState() const override { return false; }
|
||||
};
|
||||
|
||||
@@ -200,24 +206,7 @@ namespace hex {
|
||||
public:
|
||||
explicit Modal(UnlocalizedString unlocalizedName, const char *icon) : View(std::move(unlocalizedName), icon) {}
|
||||
|
||||
void draw() final {
|
||||
if (this->shouldDraw()) {
|
||||
if (this->getWindowOpenState())
|
||||
ImGui::OpenPopup(View::toWindowName(this->getUnlocalizedName()).c_str());
|
||||
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
const auto title = fmt::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName()));
|
||||
if (ImGui::BeginPopupModal(title.c_str(), this->hasCloseButton() ? &this->getWindowOpenState() : nullptr, ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
|
||||
this->drawContent();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape))
|
||||
this->getWindowOpenState() = false;
|
||||
}
|
||||
}
|
||||
void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) final;
|
||||
|
||||
[[nodiscard]] virtual bool hasCloseButton() const { return true; }
|
||||
[[nodiscard]] bool shouldStoreWindowState() const override { return false; }
|
||||
@@ -227,10 +216,7 @@ namespace hex {
|
||||
public:
|
||||
explicit FullScreen() : View("FullScreen", "") {}
|
||||
|
||||
void draw() final {
|
||||
this->drawContent();
|
||||
this->drawAlwaysVisibleContent();
|
||||
}
|
||||
void draw(ImGuiWindowFlags extraFlags = ImGuiWindowFlags_None) final;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1101,13 +1101,13 @@ namespace hex {
|
||||
namespace impl {
|
||||
|
||||
void add(const std::string &typeName, ProviderCreationFunction creationFunction) {
|
||||
(void)RequestCreateProvider::subscribe([expectedName = typeName, creationFunction](const std::string &name, bool skipLoadInterface, bool selectProvider, prv::Provider **provider) {
|
||||
(void)RequestCreateProvider::subscribe([expectedName = typeName, creationFunction](const std::string &name, bool skipLoadInterface, bool selectProvider, std::shared_ptr<prv::Provider> *provider) {
|
||||
if (name != expectedName) return;
|
||||
|
||||
auto newProvider = creationFunction();
|
||||
|
||||
if (provider != nullptr) {
|
||||
*provider = newProvider.get();
|
||||
*provider = newProvider;
|
||||
ImHexApi::Provider::add(std::move(newProvider), skipLoadInterface, selectProvider);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -294,8 +294,8 @@ namespace hex {
|
||||
namespace ImHexApi::Provider {
|
||||
|
||||
static i64 s_currentProvider = -1;
|
||||
static AutoReset<std::vector<std::unique_ptr<prv::Provider>>> s_providers;
|
||||
static AutoReset<std::map<prv::Provider*, std::unique_ptr<prv::Provider>>> s_providersToRemove;
|
||||
static AutoReset<std::vector<std::shared_ptr<prv::Provider>>> s_providers;
|
||||
static AutoReset<std::map<prv::Provider*, std::shared_ptr<prv::Provider>>> s_providersToRemove;
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -382,7 +382,7 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
void add(std::unique_ptr<prv::Provider> &&provider, bool skipLoadInterface, bool select) {
|
||||
void add(std::shared_ptr<prv::Provider> &&provider, bool skipLoadInterface, bool select) {
|
||||
std::scoped_lock lock(impl::s_providerMutex);
|
||||
|
||||
if (TaskManager::getRunningTaskCount() > 0)
|
||||
@@ -391,7 +391,7 @@ namespace hex {
|
||||
if (skipLoadInterface)
|
||||
provider->skipLoadInterface();
|
||||
|
||||
EventProviderCreated::post(provider.get());
|
||||
EventProviderCreated::post(provider);
|
||||
s_providers->emplace_back(std::move(provider));
|
||||
|
||||
if (select || s_providers->size() == 1)
|
||||
@@ -491,13 +491,17 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
prv::Provider* createProvider(const UnlocalizedString &unlocalizedName, bool skipLoadInterface, bool select) {
|
||||
prv::Provider* result = nullptr;
|
||||
std::shared_ptr<prv::Provider> createProvider(const UnlocalizedString &unlocalizedName, bool skipLoadInterface, bool select) {
|
||||
std::shared_ptr<prv::Provider> result = nullptr;
|
||||
RequestCreateProvider::post(unlocalizedName, skipLoadInterface, select, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void openProvider(std::shared_ptr<prv::Provider> provider) {
|
||||
RequestOpenProvider::post(provider);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ImHexApi::System {
|
||||
@@ -673,7 +677,7 @@ namespace hex {
|
||||
return std::midpoint(xScale, yScale);
|
||||
}
|
||||
#elif defined(OS_WEB)
|
||||
return 1.0F;
|
||||
return MAIN_THREAD_EM_ASM_INT({ return window.devicePixelRatio; });
|
||||
#else
|
||||
return 1.0F;
|
||||
#endif
|
||||
|
||||
@@ -329,12 +329,13 @@ namespace hex {
|
||||
if (ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId))
|
||||
return true;
|
||||
|
||||
const bool currentlyTyping = ImGui::GetIO().WantTextInput;
|
||||
|
||||
auto it = shortcuts.find(shortcut + AllowWhileTyping);
|
||||
if (!currentlyTyping && it == shortcuts.end()) {
|
||||
auto it = shortcuts.end();
|
||||
if (ImGui::GetIO().WantTextInput) {
|
||||
it = shortcuts.find(shortcut + AllowWhileTyping);
|
||||
} else {
|
||||
it = shortcuts.find(shortcut);
|
||||
if (it == shortcuts.end())
|
||||
it = shortcuts.find(shortcut);
|
||||
it = shortcuts.find(shortcut + AllowWhileTyping);
|
||||
}
|
||||
|
||||
if (it != shortcuts.end()) {
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <ranges>
|
||||
|
||||
#include <jthread.hpp>
|
||||
#include <hex/helpers/debugging.hpp>
|
||||
#include <hex/trace/exceptions.hpp>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
@@ -310,6 +312,8 @@ namespace hex {
|
||||
}
|
||||
|
||||
try {
|
||||
trace::enableExceptionCaptureForCurrentThread();
|
||||
|
||||
// Set the thread name to the name of the task
|
||||
TaskManager::setCurrentThreadName(Lang(task->m_unlocalizedName));
|
||||
|
||||
@@ -323,15 +327,21 @@ namespace hex {
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Exception in task '{}': {}", task->m_unlocalizedName.get(), e.what());
|
||||
|
||||
dbg::printStackTrace(trace::getStackTrace());
|
||||
|
||||
// Handle the task throwing an uncaught exception
|
||||
task->exception(e.what());
|
||||
} catch (...) {
|
||||
log::error("Exception in task '{}'", task->m_unlocalizedName.get());
|
||||
|
||||
dbg::printStackTrace(trace::getStackTrace());
|
||||
|
||||
// Handle the task throwing an uncaught exception of unknown type
|
||||
task->exception("Unknown Exception");
|
||||
}
|
||||
|
||||
trace::disableExceptionCaptureForCurrentThread();
|
||||
|
||||
s_currentTask = nullptr;
|
||||
task->finish();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include <hex/helpers/debugging.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/trace/stacktrace.hpp>
|
||||
|
||||
namespace hex::dbg {
|
||||
|
||||
@@ -21,4 +23,23 @@ namespace hex::dbg {
|
||||
s_debugMode = enabled;
|
||||
}
|
||||
|
||||
[[noreturn]] void assertionHandler(const char* file, int line, const char *function, const char* exprString) {
|
||||
log::error("Assertion failed: {} at {}:{} => {}", exprString, file, line, function);
|
||||
|
||||
const auto stackTrace = trace::getStackTrace();
|
||||
dbg::printStackTrace(stackTrace);
|
||||
|
||||
std::abort();
|
||||
}
|
||||
|
||||
void printStackTrace(const trace::StackTraceResult &stackTrace) {
|
||||
log::fatal("Printing stacktrace using implementation '{}'", stackTrace.implementationName);
|
||||
for (const auto &stackFrame : stackTrace.stackFrames) {
|
||||
if (stackFrame.line == 0)
|
||||
log::fatal(" ({}) | {}", stackFrame.file, stackFrame.function);
|
||||
else
|
||||
log::fatal(" ({}:{}) | {}", stackFrame.file, stackFrame.line, stackFrame.function);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -97,6 +97,13 @@ namespace hex::paths {
|
||||
}
|
||||
|
||||
static std::vector<std::fs::path> getPluginPaths() {
|
||||
// If running from an AppImage, only allow loaded plugins from inside it
|
||||
#if defined(OS_LINUX)
|
||||
if(const char* appdir = std::getenv("APPDIR")) { // check for AppImage environment
|
||||
return {std::string(appdir) + "/usr/lib/imhex"};
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<std::fs::path> paths = getDataPaths(true);
|
||||
|
||||
// Add the system plugin directory to the path if one was provided at compile time
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <fmt/chrono.h>
|
||||
#include <hex/helpers/debugging.hpp>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <Windows.h>
|
||||
@@ -149,14 +150,6 @@ namespace hex::log {
|
||||
);
|
||||
}
|
||||
|
||||
void assertionHandler(const char* exprString, const char* file, int line) {
|
||||
log::error("Assertion failed: {} at {}:{}", exprString, file, line);
|
||||
|
||||
#if defined (DEBUG)
|
||||
std::abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace color {
|
||||
|
||||
fmt::color debug() { return fmt::color::medium_sea_green; }
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace hex {
|
||||
[[nodiscard]] bool isSavable() const override { return false; }
|
||||
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override { return true; }
|
||||
[[nodiscard]] OpenResult open() override { return {}; }
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override {
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
#elif defined(OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <spawn.h>
|
||||
#include <hex/helpers/utils_linux.hpp>
|
||||
#elif defined(OS_MACOS)
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <spawn.h>
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#elif defined(OS_WEB)
|
||||
@@ -309,6 +311,86 @@ namespace hex {
|
||||
return ::system(command.c_str());
|
||||
}
|
||||
|
||||
std::optional<std::string> executeCommandWithOutput(const std::string &command) {
|
||||
std::array<char, 256> buffer = {};
|
||||
std::string result;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
FILE* pipe = _popen(command.c_str(), "r");
|
||||
#else
|
||||
FILE* pipe = popen(command.c_str(), "r");
|
||||
#endif
|
||||
|
||||
if (!pipe) {
|
||||
hex::log::error("Failed to open pipe for command: {}", command);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
try {
|
||||
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
|
||||
result += buffer.data();
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
hex::log::error("Exception while reading command output: {}", e.what());
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
_pclose(pipe);
|
||||
#else
|
||||
pclose(pipe);
|
||||
#endif
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
int exitCode = _pclose(pipe);
|
||||
#else
|
||||
int exitCode = pclose(pipe);
|
||||
#endif
|
||||
|
||||
if (exitCode != 0) {
|
||||
hex::log::debug("Command exited with code {}: {}", exitCode, command);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void executeCommandDetach(const std::string &command) {
|
||||
#if defined(OS_WINDOWS)
|
||||
STARTUPINFOA si = { };
|
||||
PROCESS_INFORMATION pi = { };
|
||||
si.cb = sizeof(si);
|
||||
|
||||
DWORD flags = CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW;
|
||||
std::string cmdCopy = command;
|
||||
|
||||
BOOL result = ::CreateProcessA(
|
||||
nullptr,
|
||||
cmdCopy.data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
false,
|
||||
flags,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&si,
|
||||
&pi
|
||||
);
|
||||
|
||||
if (result) {
|
||||
::CloseHandle(pi.hProcess);
|
||||
::CloseHandle(pi.hThread);
|
||||
}
|
||||
#elif defined(OS_MACOS) || defined(OS_LINUX)
|
||||
pid_t pid;
|
||||
const char* argv[] = { "sh", "-c", command.c_str(), nullptr };
|
||||
|
||||
::posix_spawnp(&pid, "sh", nullptr, nullptr, const_cast<char* const*>(argv), nullptr);
|
||||
#elif defined(OS_WEB)
|
||||
std::ignore = command;
|
||||
#endif
|
||||
}
|
||||
|
||||
void openWebpage(std::string url) {
|
||||
if (!url.contains("://"))
|
||||
url = "https://" + url;
|
||||
|
||||
@@ -11,9 +11,9 @@ namespace hex::prv {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
bool CachedProvider::open() {
|
||||
Provider::OpenResult CachedProvider::open() {
|
||||
clearCache();
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
void CachedProvider::close() {
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
bool MemoryProvider::open() {
|
||||
Provider::OpenResult MemoryProvider::open() {
|
||||
if (m_data.empty()) {
|
||||
m_data.resize(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
void MemoryProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
|
||||
#include <hex/api/imhex_api/provider.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
@@ -116,4 +118,63 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
void View::Window::draw(ImGuiWindowFlags extraFlags) {
|
||||
if (this->shouldDraw()) {
|
||||
if (!allowScroll())
|
||||
extraFlags |= ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
const auto title = fmt::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName()));
|
||||
if (ImGui::Begin(title.c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | extraFlags | this->getWindowFlags())) {
|
||||
TutorialManager::setLastItemInteractiveHelpPopup([this]{ this->drawHelpText(); });
|
||||
this->drawContent();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void View::Special::draw(ImGuiWindowFlags extraFlags) {
|
||||
std::ignore = extraFlags;
|
||||
|
||||
if (this->shouldDraw()) {
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
this->drawContent();
|
||||
}
|
||||
}
|
||||
|
||||
void View::Floating::draw(ImGuiWindowFlags extraFlags) {
|
||||
Window::draw(extraFlags | ImGuiWindowFlags_NoDocking);
|
||||
}
|
||||
|
||||
void View::Scrolling::draw(ImGuiWindowFlags extraFlags) {
|
||||
Window::draw(extraFlags);
|
||||
}
|
||||
|
||||
void View::Modal::draw(ImGuiWindowFlags extraFlags) {
|
||||
if (this->shouldDraw()) {
|
||||
if (this->getWindowOpenState())
|
||||
ImGui::OpenPopup(View::toWindowName(this->getUnlocalizedName()).c_str());
|
||||
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
const auto title = fmt::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName()));
|
||||
if (ImGui::BeginPopupModal(title.c_str(), this->hasCloseButton() ? &this->getWindowOpenState() : nullptr, ImGuiWindowFlags_NoCollapse | extraFlags | this->getWindowFlags())) {
|
||||
this->drawContent();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape))
|
||||
this->getWindowOpenState() = false;
|
||||
}
|
||||
}
|
||||
|
||||
void View::FullScreen::draw(ImGuiWindowFlags extraFlags) {
|
||||
std::ignore = extraFlags;
|
||||
|
||||
this->drawContent();
|
||||
this->drawAlwaysVisibleContent();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
2
lib/third_party/.clang-tidy
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Disable all checks
|
||||
Checks: '-*'
|
||||
13
lib/third_party/imgui/imgui/include/imconfig.h
vendored
@@ -25,10 +25,17 @@
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
namespace hex::log::impl {
|
||||
void assertionHandler(const char* expr_str, const char* file, int line);
|
||||
namespace hex::dbg {
|
||||
[[noreturn]] void assertionHandler(const char* file, int line, const char *function, const char* exprString);
|
||||
}
|
||||
#define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::log::impl::assertionHandler(#_EXPR, __FILE__, __LINE__); } } while(0)
|
||||
|
||||
#if defined(__PRETTY_FUNCTION__)
|
||||
#define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::dbg::assertionHandler(__FILE__, __LINE__, __PRETTY_FUNCTION__, #_EXPR); } } while(0)
|
||||
#elif defined(__FUNCSIG__)
|
||||
#define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::dbg::assertionHandler(__FILE__, __LINE__, __FUNCSIG__, #_EXPR); } } while(0)
|
||||
#else
|
||||
#define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::dbg::assertionHandler(__FILE__, __LINE__, __FUNCTION__, #_EXPR); } } while(0)
|
||||
#endif
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
|
||||
@@ -79,8 +79,8 @@ endif()
|
||||
|
||||
if (IMHEX_TRACE_EXCEPTIONS)
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
target_link_options(tracing ${LIBIMHEX_LIBRARY_TYPE_PUBLIC} "-Wl,--wrap=__cxa_throw")
|
||||
target_compile_definitions(tracing ${LIBIMHEX_LIBRARY_TYPE_PRIVATE} HEX_WRAP_CXA_THROW)
|
||||
target_link_options(tracing ${LIBIMHEX_LIBRARY_TYPE_PUBLIC} "-Wl,--wrap=_ZSt21__glibcxx_assert_failPKciS0_S0_")
|
||||
target_compile_definitions(tracing ${LIBIMHEX_LIBRARY_TYPE_PRIVATE} HEX_WRAP_GLIBCXX_ASSERT_FAIL)
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# Not supported currently
|
||||
endif()
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
|
||||
namespace hex::trace {
|
||||
|
||||
using AssertionHandler = void(*)(const char* file, int line, const char *function, const char* exprString);
|
||||
|
||||
std::optional<StackTraceResult> getLastExceptionStackTrace();
|
||||
void setAssertionHandler(AssertionHandler handler);
|
||||
|
||||
void enableExceptionCaptureForCurrentThread();
|
||||
void disableExceptionCaptureForCurrentThread();
|
||||
|
||||
}
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace hex::trace {
|
||||
|
||||
static std::optional<StackTraceResult> s_lastExceptionStackTrace;
|
||||
static thread_local std::optional<StackTraceResult> s_lastExceptionStackTrace;
|
||||
static thread_local bool s_threadExceptionCaptureEnabled = false;
|
||||
static AssertionHandler s_assertionHandler = nullptr;
|
||||
|
||||
std::optional<StackTraceResult> getLastExceptionStackTrace() {
|
||||
if (!s_lastExceptionStackTrace.has_value())
|
||||
@@ -15,24 +16,35 @@ namespace hex::trace {
|
||||
return result;
|
||||
}
|
||||
|
||||
void setAssertionHandler(AssertionHandler handler) {
|
||||
s_assertionHandler = handler;
|
||||
}
|
||||
|
||||
void enableExceptionCaptureForCurrentThread() {
|
||||
s_threadExceptionCaptureEnabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(HEX_WRAP_CXA_THROW)
|
||||
|
||||
extern "C" {
|
||||
|
||||
[[noreturn]] void __real___cxa_throw(void* thrownException, void* type, void (*destructor)(void*));
|
||||
[[noreturn]] void __wrap___cxa_throw(void* thrownException, void* type, void (*destructor)(void*)) {
|
||||
if (hex::trace::s_threadExceptionCaptureEnabled)
|
||||
hex::trace::s_lastExceptionStackTrace = hex::trace::getStackTrace();
|
||||
|
||||
__real___cxa_throw(thrownException, type, destructor);
|
||||
}
|
||||
|
||||
void disableExceptionCaptureForCurrentThread() {
|
||||
s_threadExceptionCaptureEnabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(HEX_WRAP_GLIBCXX_ASSERT_FAIL)
|
||||
|
||||
extern "C" {
|
||||
|
||||
[[noreturn]] void __real__ZSt21__glibcxx_assert_failPKciS0_S0_(const char* file, int line, const char* function, const char* condition);
|
||||
[[noreturn]] void __wrap__ZSt21__glibcxx_assert_failPKciS0_S0_(const char* file, int line, const char* function, const char* condition) {
|
||||
if (hex::trace::s_assertionHandler != nullptr) {
|
||||
hex::trace::s_assertionHandler(file, line, function, condition);
|
||||
} else {
|
||||
__real__ZSt21__glibcxx_assert_failPKciS0_S0_(file, line, function, condition);
|
||||
}
|
||||
|
||||
std::abort();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -126,12 +126,18 @@ int launchExecutable() {
|
||||
// Wait for the child process to exit
|
||||
::WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
// Clean up
|
||||
::CloseHandle(pi.hProcess);
|
||||
::CloseHandle(pi.hThread);
|
||||
::CloseHandle(hChildStdoutRead);
|
||||
// Get the exit code of the child process
|
||||
DWORD exitCode = 0;
|
||||
if (!::GetExitCodeProcess(pi.hProcess, &exitCode)) {
|
||||
exitCode = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
// Clean up
|
||||
::CloseHandle(pi.hProcess);
|
||||
::CloseHandle(pi.hThread);
|
||||
::CloseHandle(hChildStdoutRead);
|
||||
|
||||
return static_cast<int>(exitCode);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hex::crash {
|
||||
|
||||
using CrashCallback = void (*) (const std::string&);
|
||||
|
||||
void setCrashCallback(CrashCallback callback);
|
||||
void setupCrashHandlers();
|
||||
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <crash_handlers.hpp>
|
||||
|
||||
#include <hex/api/project_file_manager.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/workspace_manager.hpp>
|
||||
@@ -16,6 +18,7 @@
|
||||
#include <csignal>
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
#include <hex/helpers/debugging.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#if defined(IMGUI_TEST_ENGINE)
|
||||
@@ -45,8 +48,11 @@ namespace hex::crash {
|
||||
|
||||
// Function that decides what should happen on a crash
|
||||
// (either sending a message or saving a crash file, depending on when the crash occurred)
|
||||
using CrashCallback = void (*) (const std::string&);
|
||||
static CrashCallback crashCallback = sendNativeMessage;
|
||||
static CrashCallback s_crashCallback = sendNativeMessage;
|
||||
|
||||
void setCrashCallback(CrashCallback callback) {
|
||||
s_crashCallback = std::move(callback);
|
||||
}
|
||||
|
||||
static std::fs::path s_crashBackupPath;
|
||||
static void saveCrashFile(const std::string& message) {
|
||||
@@ -71,23 +77,12 @@ namespace hex::crash {
|
||||
log::warn("Could not write crash.json file!");
|
||||
}
|
||||
|
||||
static void printStackTrace() {
|
||||
auto stackTraceResult = trace::getStackTrace();
|
||||
log::fatal("Printing stacktrace using implementation '{}'", stackTraceResult.implementationName);
|
||||
for (const auto &stackFrame : stackTraceResult.stackFrames) {
|
||||
if (stackFrame.line == 0)
|
||||
log::fatal(" ({}) | {}", stackFrame.file, stackFrame.function);
|
||||
else
|
||||
log::fatal(" ({}:{}) | {}", stackFrame.file, stackFrame.line, stackFrame.function);
|
||||
}
|
||||
}
|
||||
|
||||
static void callCrashHandlers(const std::string &msg) {
|
||||
// Call the crash callback
|
||||
crashCallback(msg);
|
||||
s_crashCallback(msg);
|
||||
|
||||
// Print the stacktrace to the console or log file
|
||||
printStackTrace();
|
||||
dbg::printStackTrace(trace::getStackTrace());
|
||||
|
||||
// Flush all streams
|
||||
std::fflush(stdout);
|
||||
@@ -188,6 +183,7 @@ namespace hex::crash {
|
||||
// Setup functions to handle signals, uncaught exception, or similar stuff that will crash ImHex
|
||||
void setupCrashHandlers() {
|
||||
trace::initialize();
|
||||
trace::setAssertionHandler(dbg::assertionHandler);
|
||||
|
||||
// Register signal handlers
|
||||
{
|
||||
@@ -222,7 +218,6 @@ namespace hex::crash {
|
||||
HANDLE_SIGNAL(SIGILL);
|
||||
HANDLE_SIGNAL(SIGABRT);
|
||||
HANDLE_SIGNAL(SIGFPE);
|
||||
HANDLE_SIGNAL(SIGINT);
|
||||
|
||||
#if defined (SIGBUS)
|
||||
HANDLE_SIGNAL(SIGBUS);
|
||||
@@ -259,7 +254,7 @@ namespace hex::crash {
|
||||
|
||||
// Change the crash callback when ImHex has finished startup
|
||||
EventImHexStartupFinished::subscribe([]{
|
||||
crashCallback = saveCrashFile;
|
||||
setCrashCallback(saveCrashFile);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Handle command line arguments if any have been passed
|
||||
if (argc > 1) {
|
||||
crash::setCrashCallback([](auto){});
|
||||
init::runCommandLine(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,12 +102,12 @@ std::optional<std::fs::path> downloadUpdate(const std::string &url) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#if defined(__x86_64__) || defined(_X86_) || defined(_AMD64_) || defined(_M_X64)
|
||||
#define ARCH_DEPENDENT(x86_64, arm64) x86_64
|
||||
#elif defined(__arm64__)
|
||||
#elif defined(__arm64__) || defined(_ARM64_) || defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define ARCH_DEPENDENT(x86_64, arm64) arm64
|
||||
#else
|
||||
#define ARCH_DEPENDENT(x86_64, arm64) ""
|
||||
#error "Unsupported architecture for updater"
|
||||
#endif
|
||||
|
||||
std::string_view getUpdateArtifactEnding() {
|
||||
@@ -134,6 +134,8 @@ std::string_view getUpdateArtifactEnding() {
|
||||
return ARCH_DEPENDENT("Fedora-41-x86_64.rpm", "");
|
||||
else if (hex::executeCommand("grep -q 'VERSION_ID=\"42\"' /etc/os-release") == 0)
|
||||
return ARCH_DEPENDENT("Fedora-42-x86_64.rpm", "");
|
||||
else if (hex::executeCommand("grep -q 'VERSION_ID=\"43\"' /etc/os-release") == 0)
|
||||
return ARCH_DEPENDENT("Fedora-43-x86_64.rpm", "");
|
||||
else if (hex::executeCommand("grep -q 'VERSION_ID=\"rawhide\"' /etc/os-release") == 0)
|
||||
return ARCH_DEPENDENT("Fedora-rawhide-x86_64.rpm", "");
|
||||
} else if (hex::executeCommand("grep -q '^NAME=\"Arch Linux\"' /etc/os-release") == 0) {
|
||||
@@ -144,33 +146,106 @@ std::string_view getUpdateArtifactEnding() {
|
||||
return "";
|
||||
}
|
||||
|
||||
auto updateCommand(std::string command) {
|
||||
return [command](const std::fs::path &updatePath) -> bool {
|
||||
const auto formattedCommand = fmt::format(fmt::runtime(command), updatePath.string());
|
||||
|
||||
hex::log::info("Starting update process with command: '{}'", formattedCommand);
|
||||
|
||||
hex::executeCommandDetach(formattedCommand);
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
auto updateMacOSBundle(const std::fs::path &updatePath) {
|
||||
// Mount the DMG
|
||||
auto mountCmd = fmt::format("hdiutil attach \"{}\" -nobrowse", updatePath.string());
|
||||
auto mountOutput = hex::executeCommandWithOutput(mountCmd);
|
||||
if (!mountOutput.has_value()) {
|
||||
hex::log::error("Failed to mount DMG");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract mount point from output
|
||||
std::string mountPoint;
|
||||
for (const auto &line : wolv::util::splitString(*mountOutput, "\n")) {
|
||||
if (line.contains("/Volumes/")) {
|
||||
auto parts = wolv::util::splitString(line, "\t");
|
||||
mountPoint = parts.back();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mountPoint.empty()) {
|
||||
hex::log::error("Failed to find mount point");
|
||||
return false;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT {
|
||||
hex::executeCommand(fmt::format("hdiutil detach \"{}\"", mountPoint));
|
||||
};
|
||||
|
||||
// Find the .app bundle in the mounted DMG
|
||||
auto findCmd = fmt::format("find \"{}\" -name '*.app' -maxdepth 1", mountPoint);
|
||||
auto appPath = hex::executeCommandWithOutput(findCmd);
|
||||
if (!appPath.has_value()) {
|
||||
hex::log::error("Failed to find .app in DMG");
|
||||
hex::executeCommand(fmt::format("hdiutil detach \"{}\"", mountPoint));
|
||||
return false;
|
||||
}
|
||||
|
||||
appPath = wolv::util::trim(*appPath);
|
||||
|
||||
if (appPath->empty()) {
|
||||
hex::log::error("Failed to find .app in DMG");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the app name
|
||||
auto appName = std::fs::path(*appPath).filename().string();
|
||||
auto installPath = fmt::format("/Applications/{}", appName);
|
||||
|
||||
// Use AppleScript to copy with elevated privileges
|
||||
auto installScript = fmt::format(
|
||||
R"(osascript -e 'do shell script "rm -rf \"{}\" && cp -R \"{}\" /Applications/" with administrator privileges')",
|
||||
installPath, *appPath
|
||||
);
|
||||
|
||||
if (hex::executeCommand(installScript) != 0) {
|
||||
hex::log::error("Failed to install update");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Launch the new version
|
||||
hex::executeCommand(fmt::format("open \"{}\"", installPath));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool installUpdate(const std::fs::path &updatePath) {
|
||||
using UpdaterFunction = std::function<bool(const std::fs::path &updatePath)>;
|
||||
struct UpdateHandler {
|
||||
std::string ending;
|
||||
std::string command;
|
||||
UpdaterFunction func;
|
||||
};
|
||||
|
||||
const static auto UpdateHandlers = {
|
||||
UpdateHandler { ".msi", "msiexec /i \"{}\" /qb" },
|
||||
UpdateHandler { ".dmg", "hdiutil attach -autoopen \"{}\"" },
|
||||
UpdateHandler { ".deb", "zenity --password | sudo -S apt install -y --fix-broken \"{}\"" },
|
||||
UpdateHandler { ".rpm", "zenity --password | sudo -S rpm -i \"{}\"" },
|
||||
UpdateHandler { ".pkg.tar.zst", "zenity --password | sudo -S pacman -Syy && sudo pacman -U --noconfirm \"{}\"" },
|
||||
UpdateHandler { ".AppImage", fmt::format("zenity --password | sudo -S cp \"{{}}\" \"{}\"", hex::getEnvironmentVariable("APPIMAGE").value_or("")) },
|
||||
UpdateHandler { ".flatpak", "zenity --password | sudo -S flatpak install -y --reinstall \"{}\"" },
|
||||
UpdateHandler { ".snap", "zenity --password | sudo -S snap install --dangerous \"{}\"" },
|
||||
UpdateHandler { .ending=".msi", .func=updateCommand("msiexec /i \"{}\" /qb") },
|
||||
UpdateHandler { .ending=".dmg", .func=updateMacOSBundle },
|
||||
UpdateHandler { .ending=".deb", .func=updateCommand("zenity --password | sudo -S apt install -y --fix-broken \"{}\"") },
|
||||
UpdateHandler { .ending=".rpm", .func=updateCommand("zenity --password | sudo -S rpm -i \"{}\"") },
|
||||
UpdateHandler { .ending=".pkg.tar.zst", .func=updateCommand("zenity --password | sudo -S pacman -Syy && sudo pacman -U --noconfirm \"{}\"") },
|
||||
UpdateHandler { .ending=".AppImage", .func=updateCommand(fmt::format(R"(zenity --password | sudo -S cp "{{}}" "{}")", hex::getEnvironmentVariable("APPIMAGE").value_or(""))) },
|
||||
UpdateHandler { .ending=".flatpak", .func=updateCommand("zenity --password | sudo -S flatpak install -y --reinstall \"{}\"") },
|
||||
UpdateHandler { .ending=".snap", .func=updateCommand("zenity --password | sudo -S snap install --dangerous \"{}\"") },
|
||||
};
|
||||
|
||||
const auto updateFileName = wolv::util::toUTF8String(updatePath.filename());
|
||||
for (const auto &handler : UpdateHandlers) {
|
||||
if (updateFileName.ends_with(handler.ending)) {
|
||||
// Install the update using the correct command
|
||||
const auto command = fmt::format(fmt::runtime(handler.command), updatePath.string());
|
||||
|
||||
hex::log::info("Starting update process with command: '{}'", command);
|
||||
hex::executeCommand(command);
|
||||
|
||||
return true;
|
||||
return handler.func(updatePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,9 +273,11 @@ int main(int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
hex::log::info("Updating ImHex...");
|
||||
|
||||
// Read the version type from the arguments
|
||||
const std::string_view versionTypeString = argv[1];
|
||||
hex::log::info("Updater started with version type: {}", versionTypeString);
|
||||
hex::log::info("Installing '{}' version of ImHex", versionTypeString);
|
||||
|
||||
// Convert the version type string to the enum value
|
||||
hex::ImHexApi::System::UpdateType updateType;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <content/views/view_hex_editor.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
#include <ui/text_editor.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@@ -21,6 +20,5 @@ namespace hex::plugin::builtin {
|
||||
|
||||
private:
|
||||
std::string m_decodedString;
|
||||
ui::TextEditor m_editor;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void setPath(const std::fs::path &path);
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void setPath(const std::fs::path &path);
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override;
|
||||
@@ -65,7 +65,7 @@ namespace hex::plugin::builtin {
|
||||
private:
|
||||
void handleFileChange();
|
||||
|
||||
bool open(bool memoryMapped);
|
||||
OpenResult open(bool memoryMapped);
|
||||
|
||||
protected:
|
||||
std::fs::path m_path;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override;
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
[[nodiscard]] bool isConnected() const;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] u64 getActualSize() const override;
|
||||
void processMemoryRegions(wolv::util::Expected<std::map<u64, std::vector<u8>>, std::string> data);
|
||||
static bool memoryRegionFilter(const std::string &search, const MemoryRegion &memoryRegion);
|
||||
bool open() override;
|
||||
OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool isSavable() const override { return m_name.empty(); }
|
||||
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace hex::plugin::builtin {
|
||||
MotorolaSRECProvider() = default;
|
||||
~MotorolaSRECProvider() override = default;
|
||||
|
||||
bool open() override;
|
||||
OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool isResizable() const override { return false; }
|
||||
[[nodiscard]] bool isSavable() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override { return true; }
|
||||
[[nodiscard]] OpenResult open() override { return {}; }
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override {
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace hex::plugin::builtin {
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
bool drawLoadInterface() override;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool drawLoadInterface() override;
|
||||
void drawSidebarInterface() override;
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
void loadSettings(const nlohmann::json &) override;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool isSavableAsRecent() const override;
|
||||
|
||||
void save() override;
|
||||
[[nodiscard]] bool open() override;
|
||||
[[nodiscard]] OpenResult open() override;
|
||||
void close() override;
|
||||
|
||||
void resizeRaw(u64 newSize) override;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/api/imhex_api/bookmarks.hpp>
|
||||
|
||||
#include <ui/text_editor.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <ui/markdown.hpp>
|
||||
|
||||
|
||||
@@ -57,10 +57,6 @@ namespace hex::plugin::builtin {
|
||||
void reloadCustomNodes();
|
||||
void updateNodePositions();
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getWindowFlags() const override {
|
||||
return ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
}
|
||||
|
||||
std::vector<Workspace*> &getWorkspaceStack() { return *m_workspaceStack; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void drawContent() override;
|
||||
[[nodiscard]] ImGuiWindowFlags getWindowFlags() const override {
|
||||
return ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
return ImGuiWindowFlags_NoNavInputs;
|
||||
}
|
||||
|
||||
bool shouldDefaultFocus() const override { return true; }
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
ImGuiWindowFlags getWindowFlags() const override {
|
||||
return View::Floating::getWindowFlags() | ImGuiWindowFlags_NoResize;
|
||||
return ImGuiWindowFlags_NoResize;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewInformation : public View::Window {
|
||||
class ViewInformation : public View::Scrolling {
|
||||
public:
|
||||
explicit ViewInformation();
|
||||
~ViewInformation() override = default;
|
||||
|
||||
@@ -66,9 +66,6 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void drawContent() override;
|
||||
[[nodiscard]] ImGuiWindowFlags getWindowFlags() const override {
|
||||
return ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
}
|
||||
|
||||
void setPopupWindowHeight(u32 height) { m_popupWindowHeight = height; }
|
||||
u32 getPopupWindowHeight() const { return m_popupWindowHeight; }
|
||||
@@ -124,13 +121,13 @@ namespace hex::plugin::builtin {
|
||||
bool m_triggerEvaluation = false;
|
||||
std::atomic<bool> m_triggerAutoEvaluate = false;
|
||||
|
||||
volatile bool m_lastEvaluationProcessed = true;
|
||||
bool m_lastEvaluationResult = false;
|
||||
std::atomic<bool> m_lastEvaluationProcessed = true;
|
||||
std::atomic<int> m_lastEvaluationResult = 0;
|
||||
|
||||
std::atomic<u32> m_runningEvaluators = 0;
|
||||
std::atomic<u32> m_runningParsers = 0;
|
||||
|
||||
bool m_changesWereParsed = false;
|
||||
std::atomic<bool> m_changesWereParsed = false;
|
||||
PerProvider<bool> m_hasUnevaluatedChanges;
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_lastEditorChangeTime;
|
||||
|
||||
@@ -152,12 +149,12 @@ namespace hex::plugin::builtin {
|
||||
std::mutex m_logMutex;
|
||||
|
||||
PerProvider<ui::TextEditor::Coordinates> m_cursorPosition;
|
||||
PerProvider<ImVec2> m_scroll;
|
||||
PerProvider<ImVec2> m_consoleScroll;
|
||||
|
||||
PerProvider<ui::TextEditor::Coordinates> m_consoleCursorPosition;
|
||||
PerProvider<bool> m_cursorNeedsUpdate;
|
||||
PerProvider<bool> m_consoleCursorNeedsUpdate;
|
||||
PerProvider<ui::TextEditor::Selection> m_selection;
|
||||
PerProvider<ui::TextEditor::Selection> m_consoleSelection;
|
||||
PerProvider<ui::TextEditor::Range> m_selection;
|
||||
PerProvider<ui::TextEditor::Range> m_consoleSelection;
|
||||
PerProvider<size_t> m_consoleLongestLineLength;
|
||||
PerProvider<ui::TextEditor::Breakpoints> m_breakpoints;
|
||||
PerProvider<std::optional<pl::core::err::PatternLanguageError>> m_lastEvaluationError;
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool shouldDraw() const override { return true; }
|
||||
[[nodiscard]] bool hasViewMenuItemEntry() const override { return false; }
|
||||
|
||||
bool allowScroll() const override { return true; }
|
||||
|
||||
private:
|
||||
std::string m_themeName;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewTools : public View::Window {
|
||||
class ViewTools : public View::Scrolling {
|
||||
public:
|
||||
ViewTools();
|
||||
~ViewTools() override = default;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
ImGuiWindowFlags getWindowFlags() const override {
|
||||
return Floating::getWindowFlags() | ImGuiWindowFlags_NoResize;
|
||||
return ImGuiWindowFlags_NoResize;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |