mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-12 10:21:17 +00:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b736dd268 | ||
|
|
5dba611eac | ||
|
|
2feb5f0f9d | ||
|
|
9c164ca597 | ||
|
|
00bccf9b2d |
@@ -569,12 +569,16 @@ on the **first** call. So:
|
||||
#endif
|
||||
```
|
||||
|
||||
**Before GTK starts**, only the environment exists. `CLI::run` (`src/OrcaSlicer.cpp`) branches on
|
||||
`GDK_BACKEND` (an `x11` prefix means the X11 opt-in). On the default path it forces `GDK_BACKEND=x11`
|
||||
when wx lacks EGL and `WAYLAND_DISPLAY` is set. It sets `WEBKIT_DISABLE_COMPOSITING_MODE=1`
|
||||
(non-replacing) only when both `DISPLAY` and `WAYLAND_DISPLAY` are set, and calls `XInitThreads()`
|
||||
**Before GTK starts**, only the environment exists. `CLI::run` (`src/OrcaSlicer.cpp`) sets the NVIDIA
|
||||
DMABUF workaround and then branches on `GDK_BACKEND` (an `x11` prefix means the X11 opt-in). On both
|
||||
paths, when `/proc/driver/nvidia/version` exists and the linked WebKitGTK honours the switch (>= 2.44,
|
||||
`WebView::SupportsForceSharedMemory()`), it sets `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and
|
||||
`WEBKIT_FORCE_DMABUF_RENDERER=1` (non-replacing): the proprietary driver cannot back WebKit's hardware
|
||||
DMABUF renderer. On the default path it forces `GDK_BACKEND=x11` when wx lacks EGL and `WAYLAND_DISPLAY`
|
||||
is set. It sets `WEBKIT_DISABLE_COMPOSITING_MODE=1` (non-replacing) only when both `DISPLAY` and
|
||||
`WAYLAND_DISPLAY` are set and the linked WebKitGTK is older than 2.42, and calls `XInitThreads()`
|
||||
only when `DISPLAY` is set. With neither variable set, the GUI refuses to start ("Neither DISPLAY nor
|
||||
WAYLAND_DISPLAY set"). The details and the WebKit rule (c12912e0df) are in
|
||||
WAYLAND_DISPLAY set"). The details and the WebKit rules (c12912e0df) are in
|
||||
`references/webview-gl-aui-media.md` §WebKitGTK on Linux sessions.
|
||||
|
||||
**wx's own detectors**, for reference:
|
||||
|
||||
@@ -61,7 +61,8 @@ available; GTK2/WebKit1 is an opt-out configuration the GUI does not support.
|
||||
11. A web host that re-themes in place handles `EVT_WEBVIEW_RECREATED` without `Skip()`; one that
|
||||
needs a reload lets it through. §[Orca wrapper](#orca-webview-wrapper-widgetswebview)
|
||||
12. Keep `WebViewWebKit`'s destructor removing the `"wx"` handler. §[Orca wrapper](#orca-webview-wrapper-widgetswebview)
|
||||
13. Do not widen `WEBKIT_DISABLE_COMPOSITING_MODE` beyond Orca's default-path XWayland case, and never
|
||||
13. Do not widen `WEBKIT_DISABLE_COMPOSITING_MODE` beyond Orca's default-path XWayland case for
|
||||
WebKitGTK older than 2.42, and never
|
||||
make a page's progress depend only on a C++→JS callback. §[WebKitGTK on Linux](#webkitgtk-on-linux-sessions)
|
||||
14. GL attribute lists: legacy `int[]` lists end with `0` and spell out `WX_GL_RGBA` and
|
||||
`WX_GL_DOUBLEBUFFER`; `wxGLAttributes`/`wxGLContextAttrs` end with `EndList()`; MSAA is requested
|
||||
@@ -567,33 +568,66 @@ vue-resize workaround script and sets a persistent SQLite cookie store on the vi
|
||||
## WebKitGTK on Linux sessions
|
||||
|
||||
**Mechanism.** `CLI::run` (`src/OrcaSlicer.cpp`, under `#ifdef __WXGTK__`, before GTK initialises)
|
||||
branches on `GDK_BACKEND`:
|
||||
sets the NVIDIA DMABUF workaround and then branches on `GDK_BACKEND`:
|
||||
- **Both paths**, before the split: when `/proc/driver/nvidia/version` exists and the linked WebKitGTK
|
||||
honours the switch (>= 2.44, `WebView::SupportsForceSharedMemory()`), it sets
|
||||
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and `WEBKIT_FORCE_DMABUF_RENDERER=1` non-replacing. The
|
||||
proprietary driver cannot back WebKit's hardware DMABUF renderer, so the shared-memory transport keeps
|
||||
accelerated compositing instead of dropping it; `WEBKIT_FORCE_DMABUF_RENDERER` clears the
|
||||
Debian/Ubuntu/openSUSE `isNVIDIA()` early return, which otherwise returns before the FORCE_SHM check.
|
||||
- **Default path** (`GDK_BACKEND` unset or not starting with `x11`): if wx lacks EGL (`!wxHAS_EGL`) and
|
||||
`WAYLAND_DISPLAY` is set, it forces `GDK_BACKEND=x11`; it sets `WEBKIT_DISABLE_COMPOSITING_MODE=1`
|
||||
non-replacing **only** when both `DISPLAY` and `WAYLAND_DISPLAY` are non-empty (a Wayland session with
|
||||
non-replacing **only** when the linked WebKitGTK predates 2.42 (`WebView::NeedsCompositingWorkaround()`)
|
||||
**and** both `DISPLAY` and `WAYLAND_DISPLAY` are non-empty (a Wayland session with
|
||||
XWayland available — the session, not the backend GTK will pick); `XInitThreads()` runs only when
|
||||
`DISPLAY` is set.
|
||||
- **`GDK_BACKEND=x11…` opt-in path**: sets `DRI_PRIME=1` (and the NVIDIA PRIME variables when
|
||||
`/proc/driver/nvidia/version` exists), calls `XInitThreads()`, and deliberately does **not** disable
|
||||
compositing (the comment: the WebKit2GTK XWayland bug appears fixed in WebKit2GTK ≥ 2.42, and leaving
|
||||
compositing on keeps hardware acceleration for Device / Setup Wizard / login pages).
|
||||
compositing, which keeps hardware acceleration for Device / Setup Wizard / login pages.
|
||||
|
||||
Runtime backend detection elsewhere uses Orca's `is_running_on_wayland()` / `is_running_on_x11()`
|
||||
(see `references/platforms.md`), not these environment variables.
|
||||
|
||||
**Pitfall.**
|
||||
- **Rule:** On NVIDIA reach for `WEBKIT_DMABUF_RENDERER_FORCE_SHM` before
|
||||
`WEBKIT_DISABLE_COMPOSITING_MODE`. **Why:** the proprietary driver cannot back WebKit's hardware
|
||||
DMABUF renderer, leaving web views blank or slow; FORCE_SHM keeps accelerated compositing and only
|
||||
skips the hardware path, while disabling compositing drops it. Threaded scrolling is a separate,
|
||||
release-dependent default (off in 2.44/2.45, on from 2.46). `WEBKIT_DISABLE_DMABUF_RENDERER` is not a
|
||||
substitute — it is read first, leaves the transport set empty (no compositing from 2.44 on, where the
|
||||
X11/Wayland fallback renderers were removed) and has a reported crash path. On Debian/Ubuntu and
|
||||
openSUSE the `isNVIDIA()` patch returns before the FORCE_SHM check, so `WEBKIT_FORCE_DMABUF_RENDERER=1`
|
||||
must clear it first; that variable exists only in those patches. WebKit reads all of these once per
|
||||
process, before the first WebView.
|
||||
The test is `/proc/driver/nvidia/version`, so a hybrid laptop that renders on its iGPU also takes the
|
||||
shared-memory path, which is a per-frame GPU readback rather than zero-copy; exporting
|
||||
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=0` in the environment restores the hardware path.
|
||||
```cpp
|
||||
// Wrong: kills compositing and threaded scrolling (and can crash on modern WebKit)
|
||||
::setenv("WEBKIT_DISABLE_DMABUF_RENDERER", "1", false);
|
||||
// Right: keep compositing, skip only the hardware DMABUF path
|
||||
if (::access("/proc/driver/nvidia/version", F_OK) == 0 && WebView::SupportsForceSharedMemory()) {
|
||||
::setenv("WEBKIT_DMABUF_RENDERER_FORCE_SHM", "1", /*replace*/ false);
|
||||
::setenv("WEBKIT_FORCE_DMABUF_RENDERER", "1", /*replace*/ false);
|
||||
}
|
||||
```
|
||||
Cite: WebKit 2.52.6 `Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp`
|
||||
(`rendererBufferTransportMode()`), Debian `disable-nvidia-dmabuf.patch`, WebKit bug 262607.
|
||||
- **Rule:** Set `WEBKIT_DISABLE_COMPOSITING_MODE` only on the default path in Wayland sessions,
|
||||
non-replacing (`setenv(..., false)`, so a value the user already exported wins), before GTK
|
||||
initialises; never unconditionally. Keep JS-side fallbacks so a page never
|
||||
initialises; never unconditionally, and only for the WebKitGTK releases that need it (older than
|
||||
2.42, `WebView::NeedsCompositingWorkaround()`). Keep JS-side fallbacks so a page never
|
||||
waits forever for a C++→JS call.
|
||||
**Why:** WebKit2GTK accelerated compositing could fail silently under XWayland, leaving web views
|
||||
blank (Setup Wizard stuck on "Loading..."); disabling it everywhere needlessly drops hardware
|
||||
acceleration; without the JS timeout the user is stuck when the signal is lost.
|
||||
**Why:** WebKit2GTK accelerated compositing could fail silently under XWayland before 2.42, leaving
|
||||
web views blank (Setup Wizard stuck on "Loading..."); the variable also turns off threaded scrolling,
|
||||
so applying it on a newer WebKit needlessly drops both GPU compositing and async scrolling (the
|
||||
Device tab loses its smoothness); without the JS timeout the user is stuck when the signal is lost.
|
||||
```cpp
|
||||
// Wrong: unconditional, kills HW acceleration everywhere
|
||||
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", false);
|
||||
// Right (default path only): non-replacing, before GTK init, Wayland session with XWayland
|
||||
if (display && *display && wayland && *wayland)
|
||||
// Right (default path only): non-replacing, before GTK init, WebKitGTK < 2.42,
|
||||
// Wayland session with XWayland
|
||||
if (WebView::NeedsCompositingWorkaround() && display && *display && wayland && *wayland)
|
||||
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /*replace*/ false);
|
||||
```
|
||||
Cite: c12912e0df (`src/OrcaSlicer.cpp`; `resources/web/guide/0/load.js` `OnInit`
|
||||
|
||||
@@ -7478,7 +7478,7 @@ msgid "Update"
|
||||
msgstr "更新"
|
||||
|
||||
msgid "Assistant(HMS)"
|
||||
msgstr "助手(HMS)"
|
||||
msgstr "助理(HMS)"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Network plug-in v%s"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="28" height="27" viewBox="0 0 28 27" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path transform="matrix(0.9 0 0 0.9 1.4 1.35)" d="M11.9888 2.01601C12.8984 0.494662 15.1024 0.494662 16.012 2.01601L18.8677 6.79237C19.1958 7.34113 19.7339 7.73201 20.3572 7.87447L25.7821 9.11446C27.5101 9.50943 28.1913 11.6056 27.0254 12.9408L23.3652 17.1327C22.9449 17.6143 22.7394 18.2469 22.7964 18.8836L23.2936 24.4263C23.4519 26.1918 21.6687 27.4873 20.0386 26.7911L14.9209 24.6056C14.3329 24.3545 13.6679 24.3545 13.0799 24.6056L7.96209 26.7911C6.33196 27.4873 4.54887 26.1918 4.70722 24.4263L5.20434 18.8836C5.26145 18.2469 5.05595 17.6143 4.63544 17.1327L0.97533 12.9408C-0.19048 11.6056 0.490599 9.50943 2.21859 9.11446L7.64364 7.87447C8.2669 7.73201 8.80494 7.34113 9.13302 6.79237L11.9888 2.01601Z" stroke="#949494" stroke-width="2.4" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 876 B |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Qidi",
|
||||
"version": "02.04.00.17",
|
||||
"version": "02.04.00.16",
|
||||
"force_update": "0",
|
||||
"description": "Qidi configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
"extruder_clearance_height_to_lid": "120",
|
||||
"layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nLOG_Z\nG92 E0\n",
|
||||
"machine_end_gcode": "M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}",
|
||||
"machine_start_gcode": "PRINT_START BED=[bed_temperature_initial_layer_single] HOTEND=[nozzle_temperature_initial_layer] CHAMBER=[chamber_temperature]\nM83\nM140 S[bed_temperature_initial_layer_single]\nM104 S[nozzle_temperature_initial_layer]\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 3} Z0\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 6}\nG1 Z1 F600\n",
|
||||
"machine_start_gcode": "PRINT_START BED=[hot_plate_temp_initial_layer] HOTEND=[nozzle_temperature_initial_layer] CHAMBER=[chamber_temperature]\nM83\nM140 S[hot_plate_temp_initial_layer]\nM104 S[nozzle_temperature_initial_layer]\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 3} Z0\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 6}\nG1 Z1 F600\n",
|
||||
"thumbnails_format": "PNG",
|
||||
"default_filament_profile": [
|
||||
"Generic PLA @Qidi Q1 Pro 0.4 nozzle"
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
"default_filament_profile": [
|
||||
"Generic PLA @Qidi"
|
||||
],
|
||||
"machine_start_gcode": "G28\nM140 S[bed_temperature_initial_layer_single]\nM190 S[bed_temperature_initial_layer_single]\nM109 S[nozzle_temperature_initial_layer]\nG92 E-19\nG0 Y5 Z0.3 F3600\nG1 X5 E0 F2400\n",
|
||||
"machine_start_gcode": "G28\nM140 S[hot_plate_temp_initial_layer]\nM190 S[hot_plate_temp_initial_layer]\nM109 S[nozzle_temperature_initial_layer]\nG92 E-19\nG0 Y5 Z0.3 F3600\nG1 X5 E0 F2400\n",
|
||||
"machine_end_gcode": "M104 S0\nM140 S0\n;Retract the filament\nG92 E0\nG1 E-3 F300\nG28\nM84\n",
|
||||
"scan_first_layer": "0"
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"210x210/COLPIC",
|
||||
"110x110/PNG"
|
||||
],
|
||||
"machine_start_gcode": "PRINT_START\nG28\nM141 S0\nG0 Z50 F600\nM190 S[bed_temperature_initial_layer_single]\nG28 Z\nG29; mesh bed leveling ,comment this code to close it\nG0 X0 Y0 Z50 F6000\nM141 S{overall_chamber_temperature}\nM109 S[nozzle_temperature_initial_layer]\nM106 P3 S255\nM83\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 12} E{-10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 E{10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\n",
|
||||
"machine_start_gcode": "PRINT_START\nG28\nM141 S0\nG0 Z50 F600\nM190 S[hot_plate_temp_initial_layer]\nG28 Z\nG29; mesh bed leveling ,comment this code to close it\nG0 X0 Y0 Z50 F6000\nM141 S{overall_chamber_temperature}\nM109 S[nozzle_temperature_initial_layer]\nM106 P3 S255\nM83\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 12} E{-10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 E{10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\n",
|
||||
"machine_end_gcode": "M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}",
|
||||
"scan_first_layer": "0"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Work-around https://gitlab.gnome.org/GNOME/gnome-build-meta/-/issues/754
|
||||
grep -q org.freedesktop.Platform.GL.nvidia /.flatpak-info && export WEBKIT_DISABLE_DMABUF_RENDERER=1
|
||||
# WebKit's NVIDIA DMABUF workaround (gnome-build-meta#754) is applied by the
|
||||
# binary itself, gated on the runtime WebKitGTK version (src/OrcaSlicer.cpp).
|
||||
|
||||
# Work-around https://github.com/bambulab/BambuStudio/issues/3440
|
||||
# Use LC_NUMERIC instead of LC_ALL to prevent decimal separator issues
|
||||
|
||||
+18
-8
@@ -161,6 +161,7 @@ using json = nlohmann::json;
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include "slic3r/GUI/Widgets/WebView.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef SLIC3R_GUI
|
||||
@@ -1153,8 +1154,9 @@ int CLI::run(int argc, char **argv)
|
||||
// opt-in path. The ~2020-era WebKit2GTK XWayland compositor bug it
|
||||
// worked around appears fixed in WebKit2GTK >= 2.42; leaving it
|
||||
// unset preserves WebKit hardware acceleration on Device / Setup
|
||||
// Wizard / login / store. The default path still applies it on
|
||||
// XWayland sessions as a conservative fallback for older WebKit.
|
||||
// Wizard / login / store. The default path applies it only on
|
||||
// XWayland sessions and only when the linked WebKitGTK predates the
|
||||
// fix (< 2.42), as a conservative fallback for older WebKit.
|
||||
// ------------------------------------------------------------------
|
||||
{
|
||||
const char* gdk_backend = ::getenv("GDK_BACKEND");
|
||||
@@ -1162,6 +1164,14 @@ int CLI::run(int argc, char **argv)
|
||||
// honours the first backend in the comma-separated list).
|
||||
const bool x11_opt_in = gdk_backend && boost::starts_with(gdk_backend, "x11");
|
||||
|
||||
// NVIDIA's proprietary driver cannot back WebKitGTK's DMABUF renderer.
|
||||
// Force the shared-memory transport, which keeps compositing and threaded
|
||||
// scrolling; the second variable clears Debian/Ubuntu/openSUSE's isNVIDIA().
|
||||
if (::access("/proc/driver/nvidia/version", F_OK) == 0 && WebView::SupportsForceSharedMemory()) {
|
||||
::setenv("WEBKIT_DMABUF_RENDERER_FORCE_SHM", "1", /* replace */ false);
|
||||
::setenv("WEBKIT_FORCE_DMABUF_RENDERER", "1", /* replace */ false);
|
||||
}
|
||||
|
||||
if (x11_opt_in) {
|
||||
// ===== X11 / XWayland (opted in via GDK_BACKEND=x11) =====
|
||||
BOOST_LOG_TRIVIAL(info) << "GDK_BACKEND=x11 detected; applying v2.3.2 X11/XWayland workarounds.";
|
||||
@@ -1205,15 +1215,15 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
// WebKit2GTK compositing can fail under XWayland on older
|
||||
// WebKit releases. Disable it only when both DISPLAY and
|
||||
// WAYLAND_DISPLAY are set (i.e. an XWayland session is in
|
||||
// use). On pure X11 or native Wayland, compositing is left
|
||||
// enabled so WebKit retains HW acceleration.
|
||||
// WebKit2GTK accelerated compositing could fail under XWayland
|
||||
// on WebKit releases before 2.42. Disable it only then, and only
|
||||
// when both DISPLAY and WAYLAND_DISPLAY are set (an XWayland
|
||||
// session). Disabling it also turns off threaded scrolling, so on
|
||||
// newer WebKit it only costs performance.
|
||||
{
|
||||
const char* display_env_wk = ::getenv("DISPLAY");
|
||||
const char* wayland_env_wk = ::getenv("WAYLAND_DISPLAY");
|
||||
if (display_env_wk && *display_env_wk && wayland_env_wk && *wayland_env_wk) {
|
||||
if (WebView::NeedsCompositingWorkaround() && display_env_wk && *display_env_wk && wayland_env_wk && *wayland_env_wk) {
|
||||
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /* replace */ false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +429,8 @@ if [ "\$XDG_SESSION_TYPE" = "wayland" ] && [ "\$ZINK_DISABLE_OVERRIDE" != "1" ];
|
||||
export __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
|
||||
export MESA_LOADER_DRIVER_OVERRIDE=zink
|
||||
export GALLIUM_DRIVER=zink
|
||||
export WEBKIT_DISABLE_DMABUF_RENDERER=1
|
||||
# WebKit's NVIDIA DMABUF workaround is applied by the binary itself,
|
||||
# gated on the runtime WebKitGTK version (src/OrcaSlicer.cpp).
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1729,8 +1729,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
//plate->pattern_file = it->second->pattern_file;
|
||||
plate->no_light_thumbnail_file = it->second->no_light_thumbnail_file;
|
||||
plate->top_file = it->second->top_file;
|
||||
plate->pick_file = it->second->pick_file;
|
||||
plate->pattern_bbox_file = it->second->pattern_bbox_file;
|
||||
plate->pick_file = it->second->pick_file.empty();
|
||||
plate->pattern_bbox_file = it->second->pattern_bbox_file.empty();
|
||||
plate->config = it->second->config;
|
||||
|
||||
if (!plate->thumbnail_file.empty())
|
||||
|
||||
@@ -3295,7 +3295,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
m_is_role_based_fan_on.fill(false);
|
||||
m_role_based_fan_marker_layer.fill(-1);
|
||||
|
||||
m_fan_mover.reset();
|
||||
m_fan_mover.release();
|
||||
m_ordering_cache.clear();
|
||||
|
||||
// Belt printer: initialize belt-specific writer via virtual hook.
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <wx/checklst.h>
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
#include "slic3r/GUI/Widgets/Button.hpp"
|
||||
#include "slic3r/GUI/Widgets/DropDown.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
#include <utility>
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
@@ -173,26 +172,7 @@ void AMSMaterialsSetting::create()
|
||||
|
||||
Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this);
|
||||
Bind(EVT_SELECTED_COLOR, &AMSMaterialsSetting::on_picker_color, this);
|
||||
m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
|
||||
m_comboBox_filament->Bind(EVT_DROPDOWN_ITEM_ACTION, &AMSMaterialsSetting::on_toggle_favorite_filament, this);
|
||||
|
||||
// Favorites toggled in the open list are regrouped just before it opens again, so rows never move
|
||||
// under the cursor. These handlers run ahead of ComboBox's own, which then measure and show the
|
||||
// rebuilt rows; wxEVT_COMBOBOX_DROPDOWN would be too late, as ComboBox sends it after showing the list.
|
||||
auto regroup_favorites = [this]() {
|
||||
if (!m_favorites_regroup || m_comboBox_filament->is_drop_down())
|
||||
return;
|
||||
const FilamentInfos* info = selected_filament_info();
|
||||
const std::string filament_id = info ? info->filament_id : std::string();
|
||||
rebuild_filament_dropdown_items(filament_id);
|
||||
};
|
||||
m_comboBox_filament->Bind(wxEVT_LEFT_DOWN, [regroup_favorites](wxMouseEvent& e) { regroup_favorites(); e.Skip(); });
|
||||
m_comboBox_filament->Bind(wxEVT_LEFT_DCLICK, [regroup_favorites](wxMouseEvent& e) { regroup_favorites(); e.Skip(); });
|
||||
m_comboBox_filament->Bind(wxEVT_KEY_DOWN, [regroup_favorites](wxKeyEvent& e) {
|
||||
if (e.GetKeyCode() == WXK_RETURN || e.GetKeyCode() == WXK_SPACE) // the keys that open the list
|
||||
regroup_favorites();
|
||||
e.Skip();
|
||||
});
|
||||
m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
|
||||
|
||||
m_comboBox_cali_result->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_cali_result), NULL, this);
|
||||
}
|
||||
@@ -211,9 +191,11 @@ void AMSMaterialsSetting::create_panel_normal(wxWindow* parent)
|
||||
|
||||
m_sizer_filament->Add(0, 0, 0, wxEXPAND, 0);
|
||||
|
||||
#ifdef __APPLE__
|
||||
m_comboBox_filament = new wxComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
|
||||
#else
|
||||
m_comboBox_filament = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
|
||||
m_star_filled = ScalableBitmap(this, "score_star_light", 16);
|
||||
m_star_empty = ScalableBitmap(this, "score_star_outline", 16);
|
||||
#endif
|
||||
|
||||
m_sizer_filament->Add(m_comboBox_filament, 1, wxALIGN_CENTER, 0);
|
||||
|
||||
@@ -438,7 +420,6 @@ void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt)
|
||||
AMSMaterialsSetting::~AMSMaterialsSetting()
|
||||
{
|
||||
m_comboBox_filament->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
|
||||
m_comboBox_filament->Unbind(EVT_DROPDOWN_ITEM_ACTION, &AMSMaterialsSetting::on_toggle_favorite_filament, this);
|
||||
m_comboBox_cali_result->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_cali_result), NULL, this);
|
||||
}
|
||||
|
||||
@@ -550,9 +531,10 @@ void AMSMaterialsSetting::on_select_reset(wxCommandEvent& event) {
|
||||
std::string selected_ams_id;
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
if (preset_bundle) {
|
||||
const FilamentInfos* selected_info = selected_filament_info();
|
||||
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
|
||||
if (selected_info && it->filament_id.compare(selected_info->filament_id) == 0) {
|
||||
auto filament_item = map_filament_items[m_comboBox_filament->GetValue().ToStdString()];
|
||||
std::string filament_id = filament_item.filament_id;
|
||||
if (it->filament_id.compare(filament_id) == 0) {
|
||||
selected_ams_id = it->filament_id;
|
||||
break;
|
||||
}
|
||||
@@ -700,13 +682,12 @@ void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event)
|
||||
ams_setting_id = "";
|
||||
|
||||
// the combobox item
|
||||
const FilamentInfos* selected_info = selected_filament_info();
|
||||
const std::string filament_id = selected_info ? selected_info->filament_id : std::string();
|
||||
auto filament_item = map_filament_items[m_comboBox_filament->GetValue().ToStdString()];
|
||||
|
||||
// check filament info (rack-gated per-nozzle blacklist evaluation)
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
const auto& fila_check_res = sCheckFilamentInfo(preset_bundle, obj, ams_id, slot_id,
|
||||
filament_id, ams_filament_id, ams_setting_id);
|
||||
filament_item.filament_id, ams_filament_id, ams_setting_id);
|
||||
|
||||
if (const auto& prohibit_items = fila_check_res.get_items_by_action("prohibition"); !prohibit_items.empty()) {
|
||||
wxString info_msg;
|
||||
@@ -1005,133 +986,6 @@ static void _collect_filament_info(const wxString& shown_name,
|
||||
query_filament_types[shown_name] = filament.config.get_filament_type();
|
||||
}
|
||||
|
||||
static const char* AMS_FAVORITE_FILAMENT_IDS_KEY = "ams_favorite_filament_ids";
|
||||
|
||||
const AMSMaterialsSetting::FilamentInfos* AMSMaterialsSetting::selected_filament_info() const
|
||||
{
|
||||
const int selection = m_comboBox_filament->GetSelection();
|
||||
if (selection < 0 || selection >= int(m_filament_list_items.size()) || !m_filament_list_items[selection].is_filament)
|
||||
return nullptr;
|
||||
return &m_filament_list_items[selection].filament;
|
||||
}
|
||||
|
||||
std::set<std::string> AMSMaterialsSetting::load_favorite_filament_ids() const
|
||||
{
|
||||
std::set<std::string> favorite_ids;
|
||||
std::vector<std::string> values;
|
||||
const std::string serialized = wxGetApp().app_config->get(AMS_FAVORITE_FILAMENT_IDS_KEY);
|
||||
if (!serialized.empty() && Slic3r::unescape_strings_cstyle(serialized, values)) {
|
||||
favorite_ids.insert(values.begin(), values.end());
|
||||
}
|
||||
return favorite_ids;
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::save_favorite_filament_ids(const std::set<std::string>& favorite_ids)
|
||||
{
|
||||
std::vector<std::string> values(favorite_ids.begin(), favorite_ids.end());
|
||||
wxGetApp().app_config->set(AMS_FAVORITE_FILAMENT_IDS_KEY, Slic3r::escape_strings_cstyle(values));
|
||||
wxGetApp().app_config->save();
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::rebuild_filament_dropdown_items(const std::string& selected_filament_id)
|
||||
{
|
||||
std::vector<DropDown::Item> items;
|
||||
m_filament_list_items.clear();
|
||||
|
||||
auto append_header = [&items, this](const wxString& label) {
|
||||
DropDown::Item item;
|
||||
item.text = label;
|
||||
item.style = DD_ITEM_STYLE_SPLIT_ITEM | DD_ITEM_STYLE_DISABLED;
|
||||
items.push_back(item);
|
||||
m_filament_list_items.push_back(FilamentListItem{});
|
||||
};
|
||||
|
||||
auto append_filament = [&items, this](const wxString& name) {
|
||||
auto info_it = map_filament_items.find(name);
|
||||
if (info_it == map_filament_items.end())
|
||||
return;
|
||||
|
||||
DropDown::Item item;
|
||||
item.text = name;
|
||||
items.push_back(item);
|
||||
m_filament_list_items.push_back(FilamentListItem{info_it->second, true});
|
||||
};
|
||||
|
||||
// Favorites are listed again at the top under their own header. Without any, the list is the
|
||||
// plain filament list.
|
||||
const std::set<std::string> favorite_ids = load_favorite_filament_ids();
|
||||
std::vector<wxString> favorites;
|
||||
for (const wxString& name : m_sorted_filament_items) {
|
||||
auto info_it = map_filament_items.find(name);
|
||||
if (info_it != map_filament_items.end() && favorite_ids.count(info_it->second.filament_id) > 0)
|
||||
favorites.push_back(name);
|
||||
}
|
||||
if (!favorites.empty()) {
|
||||
append_header(_L("Favorite filaments"));
|
||||
for (const wxString& name : favorites)
|
||||
append_filament(name);
|
||||
append_header(_L("All filaments"));
|
||||
}
|
||||
for (const wxString& name : m_sorted_filament_items)
|
||||
append_filament(name);
|
||||
|
||||
int selection_idx = -1;
|
||||
if (!selected_filament_id.empty()) {
|
||||
for (int i = 0; i < int(m_filament_list_items.size()); ++i) {
|
||||
if (m_filament_list_items[i].is_filament && m_filament_list_items[i].filament.filament_id == selected_filament_id) {
|
||||
selection_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear() first: SetItems() keeps the old selection, and SetSelection() ignores an index equal to it,
|
||||
// which would leave the previous filament's name on the combo.
|
||||
m_comboBox_filament->Clear();
|
||||
m_comboBox_filament->SetItems(items);
|
||||
update_favorite_stars();
|
||||
m_comboBox_filament->SetSelection(selection_idx);
|
||||
m_favorites_regroup = false;
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::update_favorite_stars()
|
||||
{
|
||||
const std::set<std::string> favorite_ids = load_favorite_filament_ids();
|
||||
for (size_t i = 0; i < m_filament_list_items.size(); ++i) {
|
||||
const FilamentListItem& row = m_filament_list_items[i];
|
||||
if (row.is_filament) {
|
||||
const bool favorite = favorite_ids.count(row.filament.filament_id) > 0;
|
||||
m_comboBox_filament->SetItemActionBitmap(i, favorite ? m_star_filled.bmp() : m_star_empty.bmp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::toggle_favorite_filament(const std::string& filament_id)
|
||||
{
|
||||
if (filament_id.empty())
|
||||
return;
|
||||
|
||||
std::set<std::string> favorite_ids = load_favorite_filament_ids();
|
||||
auto iter = favorite_ids.find(filament_id);
|
||||
if (iter == favorite_ids.end())
|
||||
favorite_ids.insert(filament_id);
|
||||
else
|
||||
favorite_ids.erase(iter);
|
||||
|
||||
save_favorite_filament_ids(favorite_ids);
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::on_toggle_favorite_filament(wxCommandEvent& evt)
|
||||
{
|
||||
const int index = evt.GetInt();
|
||||
if (index < 0 || index >= int(m_filament_list_items.size()) || !m_filament_list_items[index].is_filament)
|
||||
return;
|
||||
|
||||
toggle_favorite_filament(m_filament_list_items[index].filament.filament_id);
|
||||
update_favorite_stars();
|
||||
m_favorites_regroup = true;
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_min, wxString temp_max, wxString k, wxString n)
|
||||
{
|
||||
if (!obj) return;
|
||||
@@ -1145,12 +999,13 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
|
||||
m_input_k_val->GetTextCtrl()->SetValue(k);
|
||||
m_input_n_val->GetTextCtrl()->SetValue(n);
|
||||
|
||||
wxArrayString filament_items;
|
||||
wxString bambu_filament_name;
|
||||
wxString hint_filament_name; // the hint type to be selected
|
||||
std::unordered_map<wxString, wxString> query_filament_vendors;// some information for sort
|
||||
std::unordered_map<wxString, wxString> query_filament_types; //
|
||||
|
||||
std::set<std::string> filament_id_set;
|
||||
m_sorted_filament_items.clear();
|
||||
// The alias keyed map has to start empty: it is a member, so a stale alias left by an earlier
|
||||
// popup (a different printer, a different nozzle) would resolve to that printer's filament_id.
|
||||
map_filament_items.clear();
|
||||
@@ -1180,7 +1035,7 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
|
||||
if (alias.empty())
|
||||
continue;
|
||||
|
||||
m_sorted_filament_items.push_back(alias);
|
||||
filament_items.push_back(alias);
|
||||
_collect_filament_info(alias, *filament_it, query_filament_vendors, query_filament_types);
|
||||
|
||||
FilamentInfos filament_infos;
|
||||
@@ -1189,6 +1044,7 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
|
||||
map_filament_items[alias] = filament_infos;
|
||||
|
||||
if (filament_it->filament_id == ams_filament_id) {
|
||||
hint_filament_name = from_u8(alias);
|
||||
bambu_filament_name = from_u8(alias);
|
||||
|
||||
|
||||
@@ -1359,11 +1215,24 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
|
||||
return name_compare != 0 ? name_compare < 0 : left < right;
|
||||
};
|
||||
|
||||
std::sort(m_sorted_filament_items.begin(), m_sorted_filament_items.end(), _filament_sorter);
|
||||
std::sort(filament_items.begin(), filament_items.end(), _filament_sorter);
|
||||
}
|
||||
|
||||
rebuild_filament_dropdown_items(ams_filament_id);
|
||||
int selection_idx = m_comboBox_filament->GetSelection();
|
||||
// traverse the hint selection idx
|
||||
int selection_idx = -1;
|
||||
{
|
||||
for(int i = 0; i < filament_items.size(); i++)
|
||||
{
|
||||
if (hint_filament_name == filament_items[i])
|
||||
{
|
||||
selection_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_comboBox_filament->Set(filament_items);
|
||||
m_comboBox_filament->SetSelection(selection_idx);
|
||||
post_select_event(selection_idx);
|
||||
|
||||
if (selection_idx < 0) {
|
||||
@@ -1420,7 +1289,6 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
||||
int* from_printer = static_cast<int*>(m_comboBox_filament->GetClientData());
|
||||
|
||||
m_filament_type = "";
|
||||
const FilamentInfos* selected_info = selected_filament_info();
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
if (preset_bundle) {
|
||||
std::ostringstream stream;
|
||||
@@ -1441,8 +1309,9 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
||||
std::string nozzle_diameter_str = stream.str();
|
||||
// Resolve the selection against the same list Popup() built the dropdown from, so the two
|
||||
// halves of the dialog cannot disagree about which filaments this machine can use.
|
||||
if (selected_info) {
|
||||
const std::string& filament_id = selected_info->filament_id;
|
||||
const std::string selected = m_comboBox_filament->GetValue().ToStdString();
|
||||
if (!selected.empty()) {
|
||||
const std::string filament_id = map_filament_items[selected].filament_id;
|
||||
for (Preset *it : preset_bundle->get_filament_presets_for_machine(
|
||||
DevPrinterConfigUtil::get_printer_display_name(obj->printer_type), nozzle_diameter_str, obj->is_support_user_preset)) {
|
||||
if (it->filament_id != filament_id)
|
||||
@@ -1495,7 +1364,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
||||
//reset cali
|
||||
int cali_select_idx = -1;
|
||||
|
||||
if ( !this->obj || m_filament_selection < 0 || !selected_info) {
|
||||
if ( !this->obj || m_filament_selection < 0) {
|
||||
m_input_k_val->Enable(false);
|
||||
m_input_n_val->Enable(false);
|
||||
m_button_confirm->Disable(); // ORCA No need to change style
|
||||
@@ -1514,9 +1383,21 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
||||
ams_filament_id = "";
|
||||
ams_setting_id = "";
|
||||
|
||||
if (selected_info) {
|
||||
ams_filament_id = selected_info->filament_id;
|
||||
ams_setting_id = selected_info->setting_id;
|
||||
if (preset_bundle) {
|
||||
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
|
||||
auto itor = map_filament_items.find(m_comboBox_filament->GetValue().ToStdString());
|
||||
if ( itor != map_filament_items.end()) {
|
||||
ams_filament_id = itor->second.filament_id;
|
||||
ams_setting_id = itor->second.setting_id;
|
||||
break;
|
||||
}
|
||||
|
||||
if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) {
|
||||
ams_filament_id = it->filament_id;
|
||||
ams_setting_id = it->setting_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxArrayString items;
|
||||
@@ -1648,11 +1529,6 @@ void AMSMaterialsSetting::on_dpi_changed(const wxRect &suggested_rect)
|
||||
m_button_reset->Rescale(); // ORCA
|
||||
m_button_confirm->Rescale(); // ORCA
|
||||
m_button_close->Rescale(); // ORCA
|
||||
// An open list would keep the measurements of the old stars, so close it before replacing them.
|
||||
m_comboBox_filament->CloseDropdown();
|
||||
m_star_filled.msw_rescale();
|
||||
m_star_empty.msw_rescale();
|
||||
update_favorite_stars();
|
||||
this->Refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "slic3r/GUI/Widgets/StateColor.hpp"
|
||||
#include <wx/panel.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#define AMS_MATERIALS_SETTING_DEF_COLOUR wxColour(255, 255, 255)
|
||||
#define AMS_MATERIALS_SETTING_GREY900 wxColour(38, 46, 48)
|
||||
@@ -157,7 +156,6 @@ protected:
|
||||
void create_panel_kn(wxWindow* parent);
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
void on_select_filament(wxCommandEvent& evt);
|
||||
void on_toggle_favorite_filament(wxCommandEvent& evt);
|
||||
void on_select_cali_result(wxCommandEvent &evt);
|
||||
void on_select_ok(wxCommandEvent &event);
|
||||
void on_select_reset(wxCommandEvent &event);
|
||||
@@ -165,11 +163,6 @@ protected:
|
||||
void on_clr_picker(wxMouseEvent &event);
|
||||
bool is_virtual_tray();
|
||||
void update_widgets();
|
||||
void rebuild_filament_dropdown_items(const std::string& selected_filament_id);
|
||||
void update_favorite_stars();
|
||||
std::set<std::string> load_favorite_filament_ids() const;
|
||||
void save_favorite_filament_ids(const std::set<std::string>& favorite_ids);
|
||||
void toggle_favorite_filament(const std::string& filament_id);
|
||||
|
||||
void update_filament_editing(bool is_printing);
|
||||
// Orca: the variant index of the filament's per-variant options on the nozzle this tray feeds
|
||||
@@ -209,7 +202,12 @@ protected:
|
||||
|
||||
int m_pa_cali_select_id = 0;
|
||||
|
||||
// Orca: native wxComboBox on macOS (the custom ComboBox mis-renders the filament dropdown there)
|
||||
#ifdef __APPLE__
|
||||
wxComboBox *m_comboBox_filament;
|
||||
#else
|
||||
ComboBox *m_comboBox_filament;
|
||||
#endif
|
||||
ComboBox * m_comboBox_cali_result;
|
||||
TextInput* m_readonly_filament;
|
||||
|
||||
@@ -217,20 +215,7 @@ protected:
|
||||
std::string filament_id;
|
||||
std::string setting_id;
|
||||
};
|
||||
struct FilamentListItem {
|
||||
FilamentInfos filament;
|
||||
bool is_filament{false};
|
||||
};
|
||||
const FilamentInfos* selected_filament_info() const;
|
||||
|
||||
// Keyed by the same wxString the dropdown shows, so a row's name never has to be converted back.
|
||||
std::map<wxString, FilamentInfos> map_filament_items;
|
||||
std::vector<wxString> m_sorted_filament_items;
|
||||
std::vector<FilamentListItem> m_filament_list_items;
|
||||
ScalableBitmap m_star_filled;
|
||||
ScalableBitmap m_star_empty;
|
||||
// Favorites changed while the list was open; their rows are regrouped before it opens again.
|
||||
bool m_favorites_regroup{false};
|
||||
std::map<std::string, FilamentInfos> map_filament_items;
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(EVT_SELECTED_COLOR, wxCommandEvent);
|
||||
|
||||
@@ -3232,16 +3232,9 @@ bool GUI_App::on_init_inner()
|
||||
#ifdef _MSW_DARK_MODE
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
// The label colours and the dark mode flag were set above from the saved mode. When the system theme
|
||||
// differs from it, refresh them, or dialogs that map their colours stay in the old mode for this session.
|
||||
const bool saved_dark_mode = dark_mode();
|
||||
wxSystemAppearance app = wxSystemSettings::GetAppearance();
|
||||
GUI::wxGetApp().app_config->set("dark_color_mode", app.IsDark() ? "1" : "0");
|
||||
GUI::wxGetApp().app_config->save();
|
||||
if (dark_mode() != saved_dark_mode) {
|
||||
init_label_colours();
|
||||
Update_dark_mode_flag();
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
|
||||
|
||||
@@ -1617,7 +1617,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx, item);
|
||||
if (obj_idx != -1) {
|
||||
Plater::TakeSnapshot snapshot(plater, _u8L("Shift objects to bed"));
|
||||
Plater::TakeSnapshot(plater, _u8L("Shift objects to bed"));
|
||||
(*m_objects)[obj_idx]->ensure_on_bed();
|
||||
cnv->reload_scene(true, true);
|
||||
update_info_items(obj_idx);
|
||||
@@ -2779,13 +2779,12 @@ void ObjectList::del_info_item(const int obj_idx, InfoItemType type)
|
||||
GLCanvas3D* cnv = plater->canvas3D();
|
||||
|
||||
switch (type) {
|
||||
case InfoItemType::CustomSupports: {
|
||||
case InfoItemType::CustomSupports:
|
||||
cnv->get_gizmos_manager().reset_all_states();
|
||||
Plater::TakeSnapshot snapshot(plater, "Remove support painting");
|
||||
Plater::TakeSnapshot(plater, "Remove support painting");
|
||||
for (ModelVolume* mv : (*m_objects)[obj_idx]->volumes)
|
||||
mv->supported_facets.reset();
|
||||
break;
|
||||
}
|
||||
|
||||
// BBS: remove CustomSeam
|
||||
|
||||
@@ -2796,21 +2795,19 @@ void ObjectList::del_info_item(const int obj_idx, InfoItemType type)
|
||||
}
|
||||
break;
|
||||
|
||||
case InfoItemType::MmSegmentation: {
|
||||
case InfoItemType::MmSegmentation:
|
||||
cnv->get_gizmos_manager().reset_all_states();
|
||||
Plater::TakeSnapshot snapshot(plater, "Remove color painting");
|
||||
Plater::TakeSnapshot(plater, "Remove color painting");
|
||||
for (ModelVolume* mv : (*m_objects)[obj_idx]->volumes)
|
||||
mv->mmu_segmentation_facets.reset();
|
||||
break;
|
||||
}
|
||||
|
||||
case InfoItemType::FuzzySkin: {
|
||||
case InfoItemType::FuzzySkin:
|
||||
cnv->get_gizmos_manager().reset_all_states();
|
||||
Plater::TakeSnapshot snapshot(plater, _u8L("Remove paint-on fuzzy skin"));
|
||||
Plater::TakeSnapshot(plater, _u8L("Remove paint-on fuzzy skin"));
|
||||
for (ModelVolume* mv : (*m_objects)[obj_idx]->volumes)
|
||||
mv->fuzzy_skin_facets.reset();
|
||||
break;
|
||||
}
|
||||
|
||||
// BBS: remove Sinking
|
||||
case InfoItemType::Undef : assert(false); break;
|
||||
@@ -6721,7 +6718,7 @@ void ObjectList::OnEditingStarted(wxDataViewEvent &event)
|
||||
else if (col == colSinking) {
|
||||
Plater * plater = wxGetApp().plater();
|
||||
GLCanvas3D *cnv = plater->canvas3D();
|
||||
Plater::TakeSnapshot snapshot(plater, _u8L("Shift objects to bed"));
|
||||
Plater::TakeSnapshot(plater, _u8L("Shift objects to bed"));
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx, item);
|
||||
(*m_objects)[obj_idx]->ensure_on_bed();
|
||||
|
||||
@@ -82,11 +82,6 @@ ComboBox::ComboBox(wxWindow *parent,
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
drop.Bind(EVT_DROPDOWN_ITEM_ACTION, [this](wxCommandEvent &e) {
|
||||
e.SetEventObject(this);
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
drop.Bind(EVT_DISMISS, [this](auto &) {
|
||||
drop_down = false;
|
||||
wxCommandEvent e(wxEVT_COMBOBOX_CLOSEUP);
|
||||
@@ -256,7 +251,7 @@ int ComboBox::Append(const wxString &text,
|
||||
int style)
|
||||
{
|
||||
auto valid_bit_map = bitmap.IsOk() ? bitmap : wxNullBitmap;
|
||||
Item item{text, wxEmptyString, valid_bit_map, valid_bit_map, wxNullBitmap, clientData, group_key, group_label};
|
||||
Item item{text, wxEmptyString, valid_bit_map, valid_bit_map, clientData, group_key, group_label};
|
||||
item.style = style;
|
||||
items.push_back(item);
|
||||
SetClientDataType(wxClientData_Void);
|
||||
@@ -302,12 +297,6 @@ void ComboBox::ForceDropdownOpen()
|
||||
}
|
||||
}
|
||||
|
||||
void ComboBox::CloseDropdown()
|
||||
{
|
||||
if (drop.IsShown())
|
||||
drop.DismissAndNotify();
|
||||
}
|
||||
|
||||
unsigned int ComboBox::GetCount() const { return items.size(); }
|
||||
|
||||
void ComboBox::set_replace_text(wxString text, wxString image_name)
|
||||
@@ -361,13 +350,6 @@ void ComboBox::SetItemBitmap(unsigned int n, wxBitmap const &bitmap)
|
||||
drop.Invalidate();
|
||||
}
|
||||
|
||||
void ComboBox::SetItemActionBitmap(unsigned int n, wxBitmap const &bitmap)
|
||||
{
|
||||
if (n >= items.size()) return;
|
||||
items[n].action_icon = bitmap.IsOk() ? bitmap : wxNullBitmap;
|
||||
drop.Invalidate();
|
||||
}
|
||||
|
||||
int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
|
||||
unsigned int pos,
|
||||
void ** clientData,
|
||||
@@ -375,7 +357,7 @@ int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
|
||||
{
|
||||
if (pos > this->items.size()) return -1;
|
||||
for (int i = 0; i < items.GetCount(); ++i) {
|
||||
Item item { items[i], wxEmptyString, wxNullBitmap, wxNullBitmap, wxNullBitmap, clientData ? clientData[i] : NULL };
|
||||
Item item { items[i], wxEmptyString, wxNullBitmap, wxNullBitmap, clientData ? clientData[i] : NULL };
|
||||
this->items.insert(this->items.begin() + pos, item);
|
||||
++pos;
|
||||
}
|
||||
@@ -437,18 +419,16 @@ void ComboBox::keyDown(wxKeyEvent& event)
|
||||
case WXK_UP:
|
||||
case WXK_DOWN:
|
||||
case WXK_LEFT:
|
||||
case WXK_RIGHT: {
|
||||
// Step over disabled rows: the mouse cannot select them either.
|
||||
const int step = (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_LEFT) ? -1 : 1;
|
||||
int n = GetSelection() + step;
|
||||
while (n >= 0 && n < int(items.size()) && (items[n].style & DD_ITEM_STYLE_DISABLED))
|
||||
n += step;
|
||||
if (n < 0 || n >= int(items.size()))
|
||||
case WXK_RIGHT:
|
||||
if ((event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_LEFT) && GetSelection() > 0) {
|
||||
SetSelection(GetSelection() - 1);
|
||||
} else if ((event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_RIGHT) && GetSelection() + 1 < items.size()) {
|
||||
SetSelection(GetSelection() + 1);
|
||||
} else {
|
||||
break;
|
||||
SetSelection(n);
|
||||
}
|
||||
sendComboBoxEvent();
|
||||
break;
|
||||
}
|
||||
case WXK_TAB:
|
||||
HandleAsNavigationKey(event);
|
||||
break;
|
||||
|
||||
@@ -96,12 +96,10 @@ public:
|
||||
|
||||
wxBitmap GetItemBitmap(unsigned int n);
|
||||
void SetItemBitmap(unsigned int n, wxBitmap const &bitmap);
|
||||
void SetItemActionBitmap(unsigned int n, wxBitmap const &bitmap);
|
||||
bool is_drop_down(){return drop_down;}
|
||||
void DeleteOneItem(unsigned int pos) { DoDeleteOneItem(pos); }
|
||||
|
||||
void ForceDropdownOpen();
|
||||
void CloseDropdown();
|
||||
|
||||
protected:
|
||||
virtual int DoInsertItems(const wxArrayStringsAdapter &items,
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
|
||||
wxDEFINE_EVENT(EVT_DISMISS, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_DROPDOWN_ITEM_ACTION, wxCommandEvent);
|
||||
|
||||
BEGIN_EVENT_TABLE(DropDown, PopupWindow)
|
||||
|
||||
@@ -243,19 +242,6 @@ static wxSize GetBmpSize(wxBitmap & bmp)
|
||||
#endif
|
||||
}
|
||||
|
||||
// The x-range [first, second) of the column at the right of the rows that holds the items' action
|
||||
// icons, empty when no item has one. render() draws the icons in it and mouseReleased() hit-tests
|
||||
// clicks against it, so the drawn icon and its clickable area always match.
|
||||
std::pair<int, int> DropDown::actionColumn() const
|
||||
{
|
||||
if (actionIconWidth <= 0)
|
||||
return {0, 0};
|
||||
int right = rowSize.x;
|
||||
if (rowSize.y * count > GetSize().y) // position bar
|
||||
right -= 6;
|
||||
return {right - actionIconWidth - FromDIP(16), right};
|
||||
}
|
||||
|
||||
static void _DrawSplitItem(const wxWindow* w, wxDC& dc, wxString split_text, wxPoint start_pt, int item_width, int item_height)
|
||||
{
|
||||
// save dc
|
||||
@@ -385,10 +371,6 @@ void DropDown::render(wxDC &dc)
|
||||
rcContent.width -= szBmp.x + 5;
|
||||
}
|
||||
|
||||
const auto action_column = actionColumn();
|
||||
if (action_column.second > action_column.first)
|
||||
rcContent.width = action_column.first - rcContent.x;
|
||||
|
||||
std::set<wxString> groups;
|
||||
// draw texts & icons
|
||||
int index = 0;
|
||||
@@ -452,24 +434,13 @@ void DropDown::render(wxDC &dc)
|
||||
auto text = group.IsEmpty()
|
||||
? (item.group_key.IsEmpty() ? item.text : item.group_label)
|
||||
: item.text;
|
||||
if (item.action_icon.IsOk()) {
|
||||
auto action_size = GetBmpSize(item.action_icon);
|
||||
wxPoint action_pt(action_column.second - action_size.x - FromDIP(8),
|
||||
rcContent.y + (rcContent.height - action_size.y) / 2);
|
||||
dc.DrawBitmap(item.action_icon, action_pt);
|
||||
}
|
||||
|
||||
if (!text_off && !text.IsEmpty()) {
|
||||
wxSize tSize = dc.GetMultiLineTextExtent(text);
|
||||
if (pt.x + tSize.x > rcContent.GetRight()) {
|
||||
int max_text_width = rcContent.GetRight() - pt.x;
|
||||
if (max_text_width <= 0) {
|
||||
text.clear();
|
||||
} else {
|
||||
if (is_hover && item.tip.IsEmpty())
|
||||
SetToolTip(text);
|
||||
text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END, max_text_width);
|
||||
}
|
||||
if (is_hover && item.tip.IsEmpty())
|
||||
SetToolTip(text);
|
||||
text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END,
|
||||
rcContent.GetRight() - pt.x);
|
||||
}
|
||||
pt.y += (rcContent.height - textSize.y) / 2;
|
||||
dc.SetFont(GetFont());
|
||||
@@ -558,7 +529,6 @@ void DropDown::messureSize()
|
||||
if (!need_sync) return;
|
||||
textSize = wxSize();
|
||||
iconSize = wxSize();
|
||||
actionIconWidth = 0;
|
||||
count = 0;
|
||||
wxClientDC dc(GetParent() ? GetParent() : this);
|
||||
dc.SetFont(GetFont());
|
||||
@@ -595,13 +565,8 @@ void DropDown::messureSize()
|
||||
size1.x += size2.x + (text_off ? 0 : 5);
|
||||
}
|
||||
}
|
||||
if (item.action_icon.IsOk())
|
||||
actionIconWidth = std::max(actionIconWidth, GetBmpSize(item.action_icon).x);
|
||||
if (size1.x > textSize.x) textSize = size1;
|
||||
}
|
||||
// Every row leaves room for the action column, as render() and actionColumn() lay it out.
|
||||
if (actionIconWidth > 0)
|
||||
textSize.x += actionIconWidth + FromDIP(16);
|
||||
if (!align_icon) iconSize.x = 0;
|
||||
wxSize szContent = textSize;
|
||||
if (szContent.x < FromDIP(120) && !use_content_width)
|
||||
@@ -671,11 +636,6 @@ void DropDown::messureSize()
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
subDropDown->Bind(EVT_DROPDOWN_ITEM_ACTION, [this](wxCommandEvent &e) {
|
||||
e.SetEventObject(this);
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
}
|
||||
need_sync = false;
|
||||
}
|
||||
@@ -754,15 +714,6 @@ void DropDown::mouseReleased(wxMouseEvent& event)
|
||||
if (hover_item < 0)
|
||||
return;
|
||||
if (hover_item >= 0 && (subDropDown == nullptr || subDropDown->group.empty())) { // not moved
|
||||
int index = hoverIndex();
|
||||
if (index >= 0 && items[index].action_icon.IsOk()) {
|
||||
const auto action_column = actionColumn();
|
||||
if (event.GetX() >= action_column.first && event.GetX() < action_column.second) {
|
||||
sendDropDownActionEvent(index);
|
||||
paintNow();
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendDropDownEvent();
|
||||
if (mainDropDown)
|
||||
mainDropDown->hover_item = -1; // To Dismiss mainDropDown
|
||||
@@ -879,17 +830,6 @@ void DropDown::sendDropDownEvent()
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void DropDown::sendDropDownActionEvent(int index)
|
||||
{
|
||||
if (index < 0 || index >= int(items.size()) || (items[index].style & DD_ITEM_STYLE_DISABLED))
|
||||
return;
|
||||
wxCommandEvent event(EVT_DROPDOWN_ITEM_ACTION, GetId());
|
||||
event.SetEventObject(this);
|
||||
event.SetInt(index);
|
||||
event.SetString(items[index].text);
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void DropDown::Dismiss()
|
||||
{
|
||||
if (subDropDown && subDropDown->IsShown())
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <wx/event.h>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <wx/gdicmn.h>
|
||||
#include "slic3r/GUI/Widgets/StateColor.hpp"
|
||||
#include <boost/date_time/posix_time/ptime.hpp>
|
||||
@@ -28,7 +27,6 @@ class wxWindow;
|
||||
#define DD_ITEM_STYLE_DIMMED 0x0004 // gray text, but still selectable
|
||||
|
||||
wxDECLARE_EVENT(EVT_DISMISS, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_DROPDOWN_ITEM_ACTION, wxCommandEvent);
|
||||
|
||||
class DropDown : public PopupWindow
|
||||
{
|
||||
@@ -39,7 +37,6 @@ public:
|
||||
wxString text_static_tips;// display static tips for TextInput.eg.PrinterInfoBox
|
||||
wxBitmap icon;
|
||||
wxBitmap icon_textctrl;// display icon for TextInput.eg.PrinterInfoBox
|
||||
wxBitmap action_icon;
|
||||
void * data{nullptr};
|
||||
wxString group_key{};
|
||||
wxString group_label{};
|
||||
@@ -68,7 +65,6 @@ private:
|
||||
|
||||
wxSize textSize;
|
||||
wxSize iconSize;
|
||||
int actionIconWidth = 0;
|
||||
wxSize rowSize;
|
||||
|
||||
StateHandler state_handler;
|
||||
@@ -139,7 +135,6 @@ private:
|
||||
int hoverIndex();
|
||||
|
||||
int selectedItem();
|
||||
std::pair<int, int> actionColumn() const;
|
||||
|
||||
friend class ComboBox;
|
||||
void messureSize();
|
||||
@@ -153,7 +148,6 @@ private:
|
||||
void mouseWheelMoved(wxMouseEvent &event);
|
||||
|
||||
void sendDropDownEvent();
|
||||
void sendDropDownActionEvent(int index);
|
||||
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
@@ -69,6 +69,10 @@ webkit_web_view_run_javascript_finish (WebKitWebView
|
||||
GError **error);
|
||||
WEBKIT_API void
|
||||
webkit_javascript_result_unref (WebKitJavascriptResult *js_result);
|
||||
WEBKIT_API guint
|
||||
webkit_get_major_version (void);
|
||||
WEBKIT_API guint
|
||||
webkit_get_minor_version (void);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -401,6 +405,29 @@ bool WebView::NeedsRecreateOnShow()
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WebView::NeedsCompositingWorkaround()
|
||||
{
|
||||
#ifdef __linux__
|
||||
const guint major = webkit_get_major_version();
|
||||
const guint minor = webkit_get_minor_version();
|
||||
return major < 2 || (major == 2 && minor < 42);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WebView::SupportsForceSharedMemory()
|
||||
{
|
||||
#ifdef __linux__
|
||||
const guint major = webkit_get_major_version();
|
||||
const guint minor = webkit_get_minor_version();
|
||||
return major > 2 || (major == 2 && minor >= 44);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if wxUSE_WEBVIEW_EDGE
|
||||
bool WebView::CheckWebViewRuntime()
|
||||
{
|
||||
|
||||
@@ -30,6 +30,16 @@ public:
|
||||
// ignoring every navigation. A panel that gets true here recreates its view on first Show().
|
||||
static bool NeedsRecreateOnShow();
|
||||
|
||||
// True when the linked WebKitGTK predates 2.42, where accelerated compositing
|
||||
// could fail silently on XWayland sessions, so it is forced off as a fallback.
|
||||
// False on every other platform. Safe to call before GTK initialises.
|
||||
static bool NeedsCompositingWorkaround();
|
||||
|
||||
// True when the linked WebKitGTK is new enough (>= 2.44) to honour
|
||||
// WEBKIT_DMABUF_RENDERER_FORCE_SHM, the shared-memory transport switch.
|
||||
// False on every other platform. Safe to call before GTK initialises.
|
||||
static bool SupportsForceSharedMemory();
|
||||
|
||||
static void RecreateAll();
|
||||
};
|
||||
|
||||
|
||||
@@ -2043,40 +2043,3 @@ TEST_CASE("3MF XML entries declaring more than an int can hold fail to load", "[
|
||||
CHECK_FALSE(parser.check_3mf_from_prusa(path));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Loading a gcode.3mf from a stream keeps the plate's pick and pattern file paths", "[3mf][Regression]")
|
||||
{
|
||||
Model model;
|
||||
REQUIRE(load_stl((std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl").c_str(), &model));
|
||||
model.add_default_instances();
|
||||
ScopedTemporaryDir backup_dir("orca_pick");
|
||||
model.set_backup_path(backup_dir.string());
|
||||
DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
|
||||
|
||||
auto plate = std::make_unique<PlateData>();
|
||||
plate->plate_index = 0;
|
||||
plate->pick_file = (backup_dir.path() / "pick.png").string();
|
||||
plate->pattern_bbox_file = (backup_dir.path() / "plate.json").string();
|
||||
|
||||
ScopedTemporaryFile temp(".3mf");
|
||||
const std::string test_file = temp.string();
|
||||
StoreParams store_params;
|
||||
store_params.path = test_file.c_str();
|
||||
store_params.model = &model;
|
||||
store_params.config = &config;
|
||||
store_params.plate_data_list.push_back(plate.get());
|
||||
store_params.strategy = SaveStrategy::Zip64 | SaveStrategy::Silence;
|
||||
REQUIRE(store_bbs_3mf(store_params));
|
||||
|
||||
boost::nowide::ifstream in(test_file, std::ios::binary);
|
||||
Model dst_model;
|
||||
DynamicPrintConfig dst_config;
|
||||
PlateDataPtrs dst_plates;
|
||||
Semver file_version;
|
||||
dst_model.set_backup_path(backup_dir.string());
|
||||
REQUIRE(load_gcode_3mf_from_stream(in, &dst_config, &dst_model, &dst_plates, &file_version));
|
||||
REQUIRE(dst_plates.size() == 1);
|
||||
CHECK(dst_plates.front()->pick_file == "Metadata/pick_1.png");
|
||||
CHECK(dst_plates.front()->pattern_bbox_file == "Metadata/plate_1.json");
|
||||
release_PlateData_list(dst_plates);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user