mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 18:01:14 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c97343811 | ||
|
|
cff514cd15 | ||
|
|
7369674d8f | ||
|
|
70da7e89bb | ||
|
|
a671bf605d | ||
|
|
bae8f64b8b |
@@ -6,7 +6,7 @@ description: Use when writing, modifying, reviewing or debugging any OrcaSlicer
|
||||
# OrcaSlicer wxWidgets GUI
|
||||
|
||||
This skill is how OrcaSlicer's wxWidgets GUI is written, changed, fixed and reviewed. Its core is
|
||||
**wxWidgets 3.3.2 API usage** — the documented contracts, the per-platform behaviour and the known
|
||||
**wxWidgets 3.3.4 API usage** — the documented contracts, the per-platform behaviour and the known
|
||||
limitations of the wx version Orca pins — layered with the OrcaSlicer conventions, wrappers, custom
|
||||
widget library and stable component designs a contributor must follow. Every reference file opens
|
||||
with a numbered **Rules** checklist (what a diff is checked against), followed by sections that give
|
||||
@@ -15,9 +15,12 @@ wrong → right pairs with the commit that fixed each one.
|
||||
|
||||
## Ground truth: the wx tree in deps/
|
||||
|
||||
Orca pins **wxWidgets 3.3.2** from the fork `github.com/SoftFever/Orca-deps-wxWidgets` (tag `v3.3.2`,
|
||||
`deps/wxWidgets/wxWidgets.cmake`), built static (Flatpak: shared). Facts about this build that change
|
||||
how you read the wx docs:
|
||||
Orca pins upstream **wxWidgets 3.3.4** (`github.com/wxWidgets/wxWidgets`, tag `v3.3.4`,
|
||||
`deps/wxWidgets/wxWidgets.cmake`), built static (Flatpak: shared). Two in-tree patches are applied: an
|
||||
Apple-only sRGB colour-component fix (`0001-macos-use-srgb-colour-components.patch`) and a Windows-only
|
||||
clang-cl sibling-compiler search fix for the installed `wxWidgetsConfig.cmake`
|
||||
(`0002-clang-cl-sibling-compiler-prefix.patch`); neither applies on Linux. Facts about this build that
|
||||
change how you read the wx docs:
|
||||
|
||||
- **Linux builds against GTK3** (`DEP_WX_GTK3` defaults ON in `deps/CMakeLists.txt`). Target GTK3 on
|
||||
both X11 and Wayland; GTK-guarded code must still compile on GTK2, an opt-out build Orca does not ship.
|
||||
@@ -33,7 +36,7 @@ Look things up in the source the app is built from — it beats memory, and 3.3
|
||||
WX=$(find -L deps -maxdepth 5 -type d -path '*dep_wxWidgets-prefix/src/dep_wxWidgets' 2>/dev/null | head -1)
|
||||
# macOS: deps/build/<arch>/dep_wxWidgets-prefix/src/dep_wxWidgets Linux, Windows: deps/<tree>/dep_wxWidgets-prefix/...
|
||||
# -L follows a worktree's deps/<tree> symlinked to the main checkout. Not a glob: zsh aborts on one that matches nothing.
|
||||
# If deps are not built: git clone --depth 1 -b v3.3.2 https://github.com/SoftFever/Orca-deps-wxWidgets
|
||||
# If deps are not built: git clone --depth 1 -b v3.3.4 https://github.com/wxWidgets/wxWidgets
|
||||
grep -n "CaptureMouse" -A 30 $WX/interface/wx/window.h # documented contract (doxygen source)
|
||||
grep -rn "@onlyfor\|not implemented" $WX/interface/wx/popupwin.h # documented platform limits
|
||||
ls $WX/docs/doxygen/overviews/ # eventhandling.h, sizer.h, high_dpi.md, windowdeletion.h, ...
|
||||
@@ -219,14 +222,15 @@ known class with a pitfall entry and a fixing commit.
|
||||
any wx key event; Control+click arrives as a right-click.
|
||||
- **Windows:** `IsDark()` and `wxSYS_COLOUR_*` follow the system app mode, not Orca's theme — use
|
||||
`dark_mode()`; menu bitmaps follow `check_dark_mode()`; windows are not double-buffered by default in
|
||||
3.3.2; `ProcessLeftDown` is never called for popups; a popup that must close with the frame calls
|
||||
3.3.4; `ProcessLeftDown` is never called for popups; a popup that must close with the frame calls
|
||||
`BindUnfocusEvent()`.
|
||||
- **Linux GTK3:** dialogs without size hints collapse (only sizer-fitting calls, not `Fit()`, are
|
||||
replayed at the first `Show()`); command events from a popup's children are not stopped at the popup
|
||||
(MSW/macOS stop them); chained popups need `transient_for` set to the mapped parent right before
|
||||
showing; native borders leak through custom widgets (`RemoveButtonBorder`/`RemoveInputBorder`).
|
||||
- **Wayland:** no global pointer position, no window positioning, `wxClientDC`, `Update()` and `SetIcon`
|
||||
do nothing, no floating AUI panes, GL is EGL only.
|
||||
do nothing, AUI floating is disabled (wx 3.3.4 can drag a floating frame via system drag sessions, but
|
||||
its docking hints still need global positions), GL is EGL only.
|
||||
|
||||
## Editing this skill
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ Contents: [Rules](#rules) · [wxColour](#wxcolour) · [System colours and appear
|
||||
|
||||
**Contract.** Constructors: `()`, `(r, g, b, a = wxALPHA_OPAQUE)`, `(unsigned long|long|int|unsigned int)` ("A
|
||||
packed RGB value", `interface/wx/colour.h:98-101`), `(const wxString&|const char*|const wchar_t*)`;
|
||||
`wxColour(bool) = delete` (`include/wx/colour.h:225-240`; `docs/changes.txt:246-248`: code "unintentionally
|
||||
`wxColour(bool) = delete` (`include/wx/colour.h:225-240`; `docs/changes.txt:278-280`: code "unintentionally
|
||||
and mistakenly using wxColour ctor from bool … doesn't compile any longer").
|
||||
|
||||
| Fact | Cite |
|
||||
@@ -121,7 +121,7 @@ returned colour is always valid" (`interface/wx/settings.h:44-48`, `:398-407`).
|
||||
|
||||
| Method | Contract |
|
||||
|---|---|
|
||||
| `IsDark()` | "checks the appearance of the current application and not the other applications on the system, so under MSW … will return false even if dark mode is used system-wide unless the application opted in using dark mode using wxApp::MSWEnableDarkMode()" (`:332-346`). An incompatible 3.3 change (`docs/changes.txt:71-73`). |
|
||||
| `IsDark()` | "checks the appearance of the current application and not the other applications on the system, so under MSW … will return false even if dark mode is used system-wide unless the application opted in using dark mode using wxApp::MSWEnableDarkMode()" (`:332-346`). An incompatible 3.3 change (`docs/changes.txt:77-79`). |
|
||||
| `AreAppsDark()` (3.3.0) | system-wide app dark mode "even if it's not enabled for this particular application"; same as `IsDark()` off MSW (`:308-321`). |
|
||||
| `IsSystemDark()` (3.3.0) | the "Windows mode", which can differ from the "app mode" (`:348-358`). |
|
||||
| `IsUsingDarkBackground()` | luminance fallback, "generally not very useful to call directly" (`:360-370`). |
|
||||
@@ -233,25 +233,25 @@ child handlers.
|
||||
`@onlyfor{wxmsw}`, `interface/wx/app.h:1418-1465`):
|
||||
- "experimental"; uses "undocumented, and unsupported by Microsoft, functions"; works on Windows 10 later than
|
||||
v1809 (including LTSC 2019) and all Windows 11; testing before 20H1 (v2004) "has been limited".
|
||||
- Flags: default follows the system ("dark mode is only used if it is the default mode for the applications on
|
||||
the current system"); `DarkMode_Always` forces dark. **[source]** `DarkMode_Auto = 0` exists in
|
||||
`include/wx/msw/app.h:48` although only `DarkMode_Always` is documented.
|
||||
- Flags: `DarkMode_Auto` (default) follows the system ("dark mode is only used if it is the default mode
|
||||
for the applications on the current system"); `DarkMode_Always` forces dark, `DarkMode_Never` forces
|
||||
light. **[source]** the enum also names `DarkMode_Auto = 0` in `include/wx/msw/app.h:46-52`;
|
||||
`DarkMode_Never` is new in 3.3.4 (documented at `interface/wx/app.h:1450-1454`).
|
||||
- Returns `true` if enabled, `false` "most likely because the system doesn't support dark mode".
|
||||
- Alternatives: the `msw.dark-mode` system option (1 = `MSWEnableDarkMode()`, 2 = `DarkMode_Always`, settable by
|
||||
environment variable from outside the app, `interface/wx/sysopt.h:85-89`), or `SetAppearance(System|Dark)`.
|
||||
- Known limitations (`interface/wx/app.h:1434-1448`): anything `TaskDialog()`-based has no dark mode —
|
||||
`wxMessageBox()`, `wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`, simple `wxAboutBox()` (wx suggests
|
||||
`wxGenericMessageDialog`/`wxGenericProgressDialog`); common-dialog wrappers `wxColourDialog`, `wxFindReplaceDialog`,
|
||||
`wxFontDialog`, `wxPageSetupDialog`, `wxPrintDialog`; `wxTimePickerCtrl`, `wxDatePickerCtrl`, `wxCalendarCtrl`
|
||||
stay light; toolbar items with `wxToolBar::SetDropdownMenu()` draw the drop-down "almost invisible".
|
||||
environment variable from outside the app, `interface/wx/sysopt.h:85-89`), or `SetAppearance(System|Light|Dark)`.
|
||||
- Known limitations (`interface/wx/app.h:1442-1448`): `wxTimePickerCtrl`, `wxDatePickerCtrl` and
|
||||
`wxCalendarCtrl` stay light; `wxPrintDialog` on Windows 10 stays light; MDI applications are not
|
||||
recommended in dark mode. `wxMessageDialog` gained dark mode in 3.3.3 (#26570) and the common dialogs
|
||||
in 3.3.4 (#26780), so the older "anything `TaskDialog()`-based and the common dialogs stay light" note
|
||||
no longer applies.
|
||||
|
||||
`AppearanceResult wxApp::SetAppearance(Appearance::System|Light|Dark)` (3.3.0, `interface/wx/app.h:1152-1190`):
|
||||
`AppearanceResult wxApp::SetAppearance(Appearance::System|Light|Dark)` (3.3.0, `interface/wx/app.h:1130-1187`):
|
||||
GTK/macOS follow the system by default and the call is immediate and "affects all the existing windows as well
|
||||
as any windows created after this call"; "Under MSW, the default appearance is always light" and an app that
|
||||
wants to follow the system must call it with `Appearance::System`; "the appearance can be only set before any
|
||||
windows are created and calling this function too late will return AppearanceResult::CannotChange" (only wxMSW
|
||||
returns it);
|
||||
`Failure` e.g. "because `GTK_THEME` is defined".
|
||||
wants to follow the system must call it with `Appearance::System`; on MSW it maps to `MSWEnableDarkMode()` and
|
||||
returns `Ok`/`Failure` (`interface/wx/app.h:1166-1169`). `Failure` e.g. "because `GTK_THEME` is defined";
|
||||
`AppearanceResult::CannotChange` is "currently never returned" (`interface/wx/app.h:1151, 1179-1183`).
|
||||
|
||||
`wxDarkModeSettings` (`interface/wx/msw/darkmode.h:30-111`), passed to `MSWEnableDarkMode()`: `GetColour(wxSystemColour)`
|
||||
(defaults "not documented and are subject to change"; the doc example names `0x202020` as the default background);
|
||||
@@ -260,34 +260,40 @@ returns it);
|
||||
which "doesn't look very well in dark mode"; the base returns grey.
|
||||
|
||||
**[source] facts the docs do not state:**
|
||||
- `SetAppearance` on MSW returns `CannotChange` when any TLW exists **or `MSWEnableDarkMode` was already called**
|
||||
(`gs_appMode != AppMode_Default`); `SetAppearance(Light)` returns `Ok` without doing anything
|
||||
(`src/msw/darkmode.cpp` `wxApp::SetAppearance`). macOS `System` sets `NSApp.appearance` to
|
||||
`[NSAppearance currentAppearance]` rather than nil, pinning the current look (`src/osx/cocoa/utils.mm:485-513`);
|
||||
GTK3 maps to the portal colour-scheme machinery; GTK2 always returns `Failure` (`src/gtk/app.cpp:355-381`).
|
||||
- `MSWEnableDarkMode` may be called any time, but dark title bars are applied only to TLWs **created** afterwards
|
||||
- As of 3.3.3 (#26516) and 3.3.4 (#26734), MSW dark mode can be switched at runtime: `SetAppearance()` maps to
|
||||
`MSWEnableDarkMode()` and returns `Ok`/`Failure`, never `CannotChange` (`src/msw/darkmode.cpp:354-375`).
|
||||
`MSWEnableDarkMode()` re-applies the mode to an existing window by sending it `WM_SYSCOLORCHANGE` (`:345-349`),
|
||||
and the window restyles through `wxMSWDarkMode::HasChanged()`/`NotifySysColorChange()`
|
||||
(`src/msw/window.cpp:5337, 5528-5534`), so a control created before the switch is re-themed too. macOS `System`
|
||||
sets `NSApp.appearance` to `[NSAppearance currentAppearance]` rather than nil, pinning the current look
|
||||
(`src/osx/cocoa/utils.mm:485-513`); GTK3 maps to the portal colour-scheme machinery; GTK2 always returns
|
||||
`Failure` (`src/gtk/app.cpp:355-381`).
|
||||
- `MSWEnableDarkMode` may be called any time; dark title bars are applied when a TLW is created
|
||||
(`EnableForTLW` at the end of TLW creation, `src/msw/toplevel.cpp:513`) and controls are dark-enabled at creation
|
||||
(`MSWCreateControl` → `AllowForWindow` and, for some controls, `SetForegroundColour(LISTBOXTEXT)`,
|
||||
`src/msw/control.cpp:133-140`). wx cannot flip existing windows — the reason `SetAppearance` refuses late calls.
|
||||
`src/msw/control.cpp:133-140`).
|
||||
- wx takes ownership of the settings pointer (`wxDarkModeModule::SetSettings`) — allocate it with `new`.
|
||||
- `msw.dark-mode` is read in `wxApp::Initialize` (`src/msw/app.cpp:492-494`): a user's `WX_MSW_DARK_MODE`
|
||||
environment variable enables wx dark mode before Orca's own call.
|
||||
- wx's owner-drawn menu path keys on `wxMSWDarkMode::IsActive()` (`src/msw/menuitem.cpp` `wxMenuItem::OnDrawItem`,
|
||||
`GetColourToUse`; `src/msw/menu.cpp`; menu-bar UAH drawing in `src/msw/darkmode.cpp`).
|
||||
|
||||
3.3.x dark-mode fix log: 3.3.2 wxMSW (`docs/changes.txt:297-308`: checkbox accessibility in dark mode, rendering of
|
||||
several controls, toolbar, menus; also "Revert use of WS_EX_COMPOSITED"), 3.3.1 (`:358-372`: wxStaticBitmap-in-notebook
|
||||
crash, disabled wxButton bitmaps and wxStaticText, notebook high-contrast background, wxDataViewCtrl light-mode
|
||||
border regression, selected toolbar buttons, wxComboCtrl, wxTE_RICH wxTextCtrl), 3.3.0 (`:385` "Add experimental dark
|
||||
mode support to wxMSW"); XRC dark colour variants (`:494`).
|
||||
3.3.x dark-mode fix log: 3.3.4 wxMSW (`docs/changes.txt:349-358`: dynamic dark mode, dark mode for
|
||||
wxFontPickerCtrl, wxNotebook, wxSpinButton and the common dialogs), 3.3.3 (`:433` "Implement support for
|
||||
switching between light/dark modes"; `:426` wxMessageDialog, `:429` combo/listbox on Windows 11, `:431`
|
||||
wxCheckBox label in screen readers), 3.3.2 (`:492-501`: checkbox accessibility in dark mode, rendering of
|
||||
several controls, toolbar, menus; also "Revert use of WS_EX_COMPOSITED"), 3.3.1 (`:553-565`:
|
||||
wxStaticBitmap-in-notebook crash, disabled wxButton bitmaps and wxStaticText, notebook high-contrast
|
||||
background, wxDataViewCtrl light-mode border regression, selected toolbar buttons, wxComboCtrl, wxTE_RICH
|
||||
wxTextCtrl), 3.3.0 (`:578` "Add experimental dark mode support to wxMSW"); XRC dark colour variants (`:687`).
|
||||
|
||||
**OrcaSlicer.** `GUI_App::on_init_inner` (`#ifdef __WINDOWS__`) calls `MSWEnableDarkMode(DarkMode_Auto)` and then
|
||||
`NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled)`. wx's call exists only so that wx-drawn
|
||||
menus get dark borders; NppDarkMode does the theming (title bars, explorer theme, scrollbars, list headers) because
|
||||
it can switch live and wx cannot. The code comment "Orca: todo switch to native dark mode support in wxWidgets and
|
||||
remove NppDarkMode" records the intent; the blocker is that a live Preferences toggle would become restart-only
|
||||
(`SetAppearance` returns `CannotChange` after startup, existing windows cannot be restyled) and TaskDialog/common
|
||||
dialogs/pickers stay light anyway — which is also why Orca has its own `MsgDialog` family and `ProgressDialog`.
|
||||
`NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled)`. wx's call exists so that wx-drawn
|
||||
menus get dark borders; NppDarkMode does Orca's theming (title bars, explorer theme, scrollbars, list headers).
|
||||
The code comment "Orca: todo switch to native dark mode support in wxWidgets and remove NppDarkMode" records the
|
||||
intent. The old blocker — a live Preferences toggle would be restart-only because `SetAppearance` returned
|
||||
`CannotChange` and existing windows could not be restyled — is gone as of 3.3.3/3.3.4 (above). Orca still keeps
|
||||
NppDarkMode, and Orca's own `MsgDialog` family and `ProgressDialog` remain its message/progress UI.
|
||||
**[source]** consequences of `DarkMode_Auto`: wx's internal "dark" stays `AllowDark` and follows the **system app
|
||||
mode**; NppDarkMode's later `SetPreferredAppMode` call does not touch wx's `gs_appMode`. So with Windows light +
|
||||
Orca dark, wx's dark machinery (menus, `GetColour()`, `IsDark()`) stays off; with Windows dark + Orca light it is
|
||||
@@ -312,11 +318,15 @@ on: `GetColour()` returns the dark palette, new native controls are dark-enabled
|
||||
```
|
||||
Cite: bf397a0632 (`GUI_App.cpp`, `GUI_App::on_init_inner`).
|
||||
- **Rule:** Do not call `wxTheApp->SetAppearance(...)` in Orca.
|
||||
**Why:** MSW returns `CannotChange` (Orca already called `MSWEnableDarkMode`), GTK2 fails, and macOS pins
|
||||
**Why:** MSW would switch wx's own mode out of step with NppDarkMode and `dark_color_mode` (wx's mode is driven
|
||||
by `MSWEnableDarkMode(DarkMode_Auto)` and follows the system), GTK2 fails, and macOS pins
|
||||
`NSApp.appearance` while `GUI_App::dark_mode()` keeps reading the system `AppleInterfaceStyle` — the two would
|
||||
disagree.
|
||||
- **Rule:** Do not show wx's TaskDialog-based or common dialogs where dark mode matters; use `MessageDialog` and
|
||||
friends (`MsgDialog.hpp`, see `references/windows-dialogs.md`).
|
||||
- **Rule:** Do not show wx's TaskDialog-based or common dialogs; use `MessageDialog` and friends
|
||||
(`MsgDialog.hpp`, see `references/windows-dialogs.md`).
|
||||
**Why:** Orca's dialogs are owner-drawn and consistent with the rest of the UI. The old dark-mode gap
|
||||
closed — `wxMessageDialog` gained dark mode in 3.3.3 (#26570) and the common dialogs in 3.3.4 (#26780) —
|
||||
but the convention stands.
|
||||
|
||||
## Window colours, inheritance and native-control limits
|
||||
|
||||
@@ -371,7 +381,7 @@ macOS paints the system grey.
|
||||
|
||||
| Port | Behaviour |
|
||||
|---|---|
|
||||
| MSW | `wxButton`/`wxToggleButton` `SetBackgroundColour`/`SetForegroundColour` switch the native button to `BS_OWNERDRAW` (`src/msw/anybutton.cpp` `wxAnyButton::MakeOwnerDrawn`, `:1324-1390`) — the colour works but native theming is gone. `wxCheckBox`/`wxRadioButton` foreground makes them owner-drawn when themes are active (`src/msw/control.cpp` `MSWMakeOwnerDrawnIfNecessary`); 3.3.2 fixed checkbox accessibility in that mode (`docs/changes.txt:299-300`). Static-text-like children paint the ancestor brush only if that ancestor's background is inheritable. |
|
||||
| MSW | `wxButton`/`wxToggleButton` `SetBackgroundColour`/`SetForegroundColour` switch the native button to `BS_OWNERDRAW` (`src/msw/anybutton.cpp` `wxAnyButton::MakeOwnerDrawn`, `:1324-1390`) — the colour works but native theming is gone. `wxCheckBox`/`wxRadioButton` foreground makes them owner-drawn when themes are active (`src/msw/control.cpp` `MSWMakeOwnerDrawnIfNecessary`); 3.3.2 fixed checkbox accessibility in that mode (`docs/changes.txt:492-493`). Static-text-like children paint the ancestor brush only if that ancestor's background is inheritable. |
|
||||
| macOS | `SetBackgroundColour` reaches the NSView only if it `respondsToSelector:setBackgroundColor:` and the style is not `wxBG_STYLE_TRANSPARENT` (`src/osx/cocoa/window.mm:3514-3531`): **NSButton (`wxButton`) ignores the background colour**. Foreground uses `setTextColor:` when the view has it (`:3885-3887`); stock NSButton has none. `wxStaticText` is an NSTextField with `setDrawsBackground:NO` — its background is never painted (`src/osx/cocoa/stattext.mm:154`). `wxTextCtrl`'s `setEnabled:` resets the text colour: multi-line (`wxNSTextView`) always, to `controlTextColor`/`disabledControlTextColor`; single-line (`wxNSTextField`) when it does not draw its background, to `controlTextColor`/`secondarySelectedControlColor` (`src/osx/cocoa/textctrl.mm`). |
|
||||
| GTK3 | `SetBackgroundColour/SetForegroundColour/SetFont` install a per-widget CSS provider `*{color:..;background:..;font:..}` at `GTK_STYLE_PROVIDER_PRIORITY_APPLICATION` (`src/gtk/window.cpp` `wxWindowGTK::GTKApplyStyle`); `wxButton`/`wxCheckBox` apply it to their inner label too (`src/gtk/button.cpp:325-335`, `src/gtk/checkbox.cpp:233-237`). User CSS (priority USER) can still override. |
|
||||
| GTK2 | colours applied with `gtk_widget_modify_style` — pixmap-engine themes may ignore them. |
|
||||
|
||||
@@ -106,7 +106,7 @@ The general wx rule is that setters do not send events. The exceptions are the b
|
||||
| `wxTextEntry::SetValue(s)` | **yes**, one `wxEVT_TEXT`, even when `s` equals the current text | `interface/wx/textentry.h:539-542`; [source] `src/common/textentrycmn.cpp:236-254`, `src/msw/textctrl.cpp:1133-1145` |
|
||||
| `wxTextEntry::ChangeValue(s)` | no | `interface/wx/textentry.h:177-178` |
|
||||
| `wxTextEntry::Clear()` | yes (= `SetValue("")`) | `interface/wx/textentry.h:193-194` |
|
||||
| `wxTextCtrl::SetLabel/SetLabelText` | nothing at all (3.3) | `docs/changes.txt:111-113`; `src/common/textcmn.cpp:934-937` |
|
||||
| `wxTextCtrl::SetLabel/SetLabelText` | nothing at all (3.3) | `docs/changes.txt:117-119`; `src/common/textcmn.cpp:934-937` |
|
||||
| `SetSelection/SetStringSelection` on wxChoice, wxComboBox, wxListBox, wxRadioBox | no | `interface/wx/ctrlsub.h:102-103,126` |
|
||||
| `wxComboBox::SetValue` | `wxEVT_TEXT` if editable; none with `wxCB_READONLY` | `interface/wx/combobox.h:256-272` |
|
||||
| `wxComboBox::Popup()/Dismiss()` | DROPDOWN/CLOSEUP, except on wxOSX | `interface/wx/combobox.h:279-281,292-294` |
|
||||
@@ -184,7 +184,7 @@ Pitfalls:
|
||||
ctrl->GetTextCtrl()->SetLabel(s); // Wrong: no-op
|
||||
ctrl->GetTextCtrl()->ChangeValue(s); // Right (or SetValue if listeners must react)
|
||||
```
|
||||
Cite: `docs/changes.txt:111-113`.
|
||||
Cite: `docs/changes.txt:117-119`.
|
||||
- **Rule:** Handle `wxEVT_TEXT_ENTER` without `Skip()` unless you want the default button activated as well.
|
||||
**Why:** a skipped Enter falls through to the dialog's default button and closes it.
|
||||
```cpp
|
||||
@@ -213,7 +213,7 @@ Contract:
|
||||
verbatim, and `wxControl::EscapeMnemonics()` escapes it (`interface/wx/control.h:174-195, 379-387`). This applies
|
||||
to `wxStaticText`, `wxCheckBox`, `wxRadioButton`, `wxButton` labels and to book page titles: all `wx*book`
|
||||
classes interpret mnemonics in page text (`interface/wx/bookctrl.h:141-147`), and since 3.3 wxListbook and
|
||||
wxChoicebook do too (`docs/changes.txt:128-130`).
|
||||
wxChoicebook do too (`docs/changes.txt:134-136`).
|
||||
- `SetLabelMarkup()` needs well-formed markup or the label "won't be shown at all" (returns false, keeps the old
|
||||
label). A bare `&` is still a mnemonic. Multi-line markup works only on GTK and macOS; the generic version used on
|
||||
MSW handles single lines (`interface/wx/control.h:338-347`). Quote untrusted text with
|
||||
@@ -383,10 +383,10 @@ Pitfalls:
|
||||
|
||||
- Virtual list (`wxLC_REPORT|wxLC_VIRTUAL`): call `SetItemCount()` and override `OnGetItemText` (optionally
|
||||
`OnGetItemImage`/`OnGetItemAttr`) (`interface/wx/listctrl.h:128-134`). `EditLabel()` asserts without
|
||||
`wxLC_EDIT_LABELS` (`docs/changes.txt:68-69`).
|
||||
`wxLC_EDIT_LABELS` (`docs/changes.txt:74-75`).
|
||||
- Images: prefer `SetImages(std::vector<wxBitmapBundle>)`; `wxImageList` is discouraged
|
||||
(`interface/wx/withimages.h:21-40`) and is measured in physical pixels in 3.3 (`docs/changes.txt:85-88`); calling
|
||||
its methods on an invalid (unsized) list now asserts, i.e. fails silently in Orca (`docs/changes.txt:53-56`).
|
||||
(`interface/wx/withimages.h:21-40`) and is measured in physical pixels in 3.3 (`docs/changes.txt:91-94`); calling
|
||||
its methods on an invalid (unsized) list now asserts, i.e. fails silently in Orca (`docs/changes.txt:59-62`).
|
||||
`Assign*` transfers ownership, `Set*ImageList` does not (`interface/wx/withimages.h:90-110`). Sizing:
|
||||
`references/dpi-bitmaps-fonts.md`.
|
||||
- `wxTreeCtrl`: `SelectItem` emits events ([table](#events-from-programmatic-changes)).
|
||||
@@ -402,7 +402,7 @@ Contract:
|
||||
selection's blocks).
|
||||
- `FreezeTo(row, col)` returns false (an assert, silent in Orca) for out-of-range values, merged cells or the native
|
||||
header (`interface/wx/grid.h:5747-5772`); [source] also when rows/columns were reordered or drag-moving is enabled
|
||||
(`src/generic/grid.cpp:5742-5750`). In 3.3 it freezes even when the grid is too small (`docs/changes.txt:48-51`).
|
||||
(`src/generic/grid.cpp:5742-5750`). In 3.3 it freezes even when the grid is too small (`docs/changes.txt:54-57`).
|
||||
- Editor contract: `EndEdit` must not modify the grid — it stores the value and returns true if it changed;
|
||||
`ApplyEdit` writes it after `wxEVT_GRID_CELL_CHANGING` was not vetoed (`interface/wx/grid.h:610-638`). Editors,
|
||||
renderers and attrs are ref-counted and the setters take ownership (`:1263-1305, 1739-1770, 2681-2701`).
|
||||
@@ -492,7 +492,7 @@ All cites `interface/wx/dataview.h`. MSW uses the generic implementation; wxGTK
|
||||
Other per-port facts: editing starts on a slow double-click or a platform key — "F2 is typical on Windows, Space
|
||||
and/or Enter is common elsewhere" (2604-2607, 1915-1918); a custom renderer's `StartDrag()` is "Not yet supported"
|
||||
(2717-2719); `RenderText()` should be used inside `Render()` so text matches native renderers (2708-2714). Calling
|
||||
`Collapse()` from an event handler was fixed in 3.3.1 (`docs/changes.txt:346`; the generic re-check is described
|
||||
`Collapse()` from an event handler was fixed in 3.3.1 (`docs/changes.txt:539`; the generic re-check is described
|
||||
under [DVC control API](#wxdataviewctrl-control-api)).
|
||||
|
||||
OrcaSlicer: `ParamsViewCtrl` (`EditGCodeDialog`) and `DiffViewCtrl` (`UnsavedChangesDialog`) use
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# DPI, bitmaps and fonts
|
||||
|
||||
How wx 3.3.2 maps DIP, logical and physical pixels on each platform, how DPI changes reach a window,
|
||||
How wx 3.3.4 maps DIP, logical and physical pixels on each platform, how DPI changes reach a window,
|
||||
and how OrcaSlicer sizes layout (`FromDIP`, `em_unit`), rescales (`DPIAware`), rasterizes icons
|
||||
(`BitmapCache`, `create_scaled_bitmap`, `ScalableBitmap`) and chooses fonts (`Label` table). Read it
|
||||
for any fixed size, icon, bitmap, image list, font, or `on_dpi_changed` work, and when a bug looks
|
||||
@@ -488,7 +488,7 @@ handler bound there runs once more after every DPI change.
|
||||
inherits the DC's scale (`interface/wx/bitmap.h:370-385`).
|
||||
- `wxBitmap(const wxCursor&)` is invalid on GTK under Wayland (`interface/wx/bitmap.h:388-401`).
|
||||
- wxMSW `wxBitmap::Create(size, dc)` no longer multiplies by the DC's content scale
|
||||
(`docs/changes.txt:94-96`).
|
||||
(`docs/changes.txt:100-102`).
|
||||
|
||||
**Offscreen drawing.** "The scaling factor of the bitmap determines the scaling factor used by
|
||||
this device context" (`interface/wx/dcmemory.h:41-58`); `wxMemoryDC(wxDC*)` does **not** inherit
|
||||
@@ -740,7 +740,7 @@ are in `references/popups-menus.md`.
|
||||
in the new code as it doesn't support showing DPI-dependent bitmaps. Please use
|
||||
wxWithImages::SetImages() instead"; "the size is specified in physical pixels and must correspond
|
||||
to the size of bitmaps … that will be added". 3.3 made the size physical and makes calls on an
|
||||
invalid list assert (`docs/changes.txt:53-56, 85-88`) — silently in Orca's assert-free build.
|
||||
invalid list assert (`docs/changes.txt:59-62, 91-94`) — silently in Orca's assert-free build.
|
||||
When a list is unavoidable, `wxBitmapBundle::CreateImageList(win, bundles)` builds one at the
|
||||
consensus size (public but undocumented, [source] `include/wx/bmpbndl.h`).
|
||||
```cpp
|
||||
@@ -761,7 +761,7 @@ wxArtProvider::GetBitmapBundle(wxART_WARNING, wxART_OTHER, wxSize(16, 16));
|
||||
```
|
||||
|
||||
**`wxImage`** resizing (`interface/wx/image.h:28-89`): `wxIMAGE_QUALITY_NEAREST` is no longer an
|
||||
alias of `NORMAL` since 3.3.0 (`docs/changes.txt:98-99`; `wxIMAGE_QUALITY_FAST` is the speed
|
||||
alias of `NORMAL` since 3.3.0 (`docs/changes.txt:104-105`; `wxIMAGE_QUALITY_FAST` is the speed
|
||||
synonym). `NORMAL` (default) = bilinear down to an integer multiple, then box average; `HIGH` =
|
||||
box average when shrinking, bicubic when enlarging; `BILINEAR`, `BICUBIC`, `BOX_AVERAGE` explicit.
|
||||
High-quality scaling "may not work as expected when using a single mask colour for
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Events: binding, dispatch, posting and deferred calls
|
||||
|
||||
How wx 3.3.2 finds, runs, propagates, queues and drops event handlers, and how OrcaSlicer code
|
||||
How wx 3.3.4 finds, runs, propagates, queues and drops event handlers, and how OrcaSlicer code
|
||||
binds, emits and defers. Read it before writing any `Bind`/`Unbind`, `Skip()`, `ProcessEvent`,
|
||||
`wxPostEvent`/`wxQueueEvent` or `CallAfter`, before defining a custom event, and when debugging a
|
||||
handler that never runs, runs twice, runs on a dead object, or swallows a widget's own behaviour.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Mouse, keyboard and focus
|
||||
|
||||
How input reaches wx windows in the wxWidgets 3.3.2 build Orca ships, and the Orca conventions on
|
||||
How input reaches wx windows in the wxWidgets 3.3.4 build Orca ships, and the Orca conventions on
|
||||
top: mouse capture, mouse and key events, accelerators and Orca's shortcut registry, focus,
|
||||
tooltips and cursors. Read it when a widget captures the mouse or tracks hover, when adding or
|
||||
changing a keyboard shortcut, when touching focus, tooltip or cursor code, and when debugging an
|
||||
@@ -297,7 +297,7 @@ Per port [source]:
|
||||
non-enter event while the cached position is invalid is treated as the enter.
|
||||
- **GTK:** crossing events with a grab/ungrab mode are ignored; outside capture wx re-derives the
|
||||
window under the pointer on each motion (`src/gtk/window.cpp:2073-2117, 2384-2456`; fixes #24339
|
||||
and #24931–#24933 are in this release, `docs/changes.txt:537, 547`).
|
||||
and #24931–#24933 are in this release, `docs/changes.txt:730, 740`).
|
||||
- **macOS:** each view's `NSTrackingArea` uses `NSTrackingInVisibleRect`
|
||||
(`src/osx/cocoa/window.mm:3924`) and covers its children, so do not rely on the parent getting
|
||||
LEAVE when the pointer moves onto a child. `NSMouseMoved` is delivered only to the deepest view
|
||||
@@ -334,7 +334,7 @@ A composite's hover state must therefore track its children. Orca's `StateHandle
|
||||
`CS_DBLCLKS`, `src/msw/app.cpp:584`). GTK drops the surplus press before `GDK_2BUTTON_PRESS`
|
||||
(`src/gtk/window.cpp:1798-1817`), and GTK2 also suppresses triple clicks (`:1818-1829`). On wxOSX the
|
||||
third press of a triple click is a DOWN again, as on MSW (`src/osx/cocoa/window.mm:4105-4140`;
|
||||
#25886, `docs/changes.txt:316`). `GetClickCount()` is "implemented only in wxMac and returns -1
|
||||
#25886, `docs/changes.txt:509`). `GetClickCount()` is "implemented only in wxMac and returns -1
|
||||
for the other platforms" (`interface/wx/event.h:2965-2974`).
|
||||
- **Context menu:** "under MSW the context menu event is generated after EVT_RIGHT_UP … but under
|
||||
GTK … after EVT_RIGHT_DOWN", so a window handling `wxEVT_CONTEXT_MENU` must not handle (or must
|
||||
@@ -398,7 +398,7 @@ A diagonal trackpad scroll on macOS sends two events, vertical first, then one w
|
||||
| `ClientToScreen()`, `ScreenToClient()`, `GetScreenRect()` | — | add the top-level window's `gdk_window_get_origin()` (`src/gtk/window.cpp:4630-4698`). Without a global origin the result is only meaningful relative to the same top-level window: fine for deltas and hit tests inside one window, wrong across windows or for absolute placement |
|
||||
| `wxFindWindowAtPoint(pt)` | deepest window at a screen point; disabled children count, hidden ones are skipped (`interface/wx/utils.h:385-394`) | built on screen rectangles, so unreliable. On GTK it is `wxGenericFindWindowAtPoint`, a walk over every top-level window and child (`src/gtk/utilsgtk.cpp:98-101`, `src/common/utilscmn.cpp:1294-1345`) |
|
||||
| `wxGetKeyState(key)` | "In wxGTK, this function can be only used with modifier keys … when not using X11 backend" (`interface/wx/utils.h:352-358`) | Ctrl/Alt/Shift and Caps/Num/Scroll Lock only; any other key returns false (`src/unix/utilsx11.cpp:2596-2662`) |
|
||||
| `WarpPointer()` | Apple's HIG forbids it; on Wayland it works only with a compositor implementing the pointer-warp protocol, and mutter also needs a pressed button (`interface/wx/window.h:3895-3914`; `docs/changes.txt:294`) | — |
|
||||
| `WarpPointer()` | Apple's HIG forbids it; on Wayland it works only with a compositor implementing the pointer-warp protocol, and mutter also needs a pressed button (`interface/wx/window.h:3895-3914`; `docs/changes.txt:487`) | — |
|
||||
| `wxUIActionSimulator` | "doesn't work when using Wayland" (`interface/wx/uiaction.h:20`) | — |
|
||||
| `PopupMenu(x, y)` | — | GTK ≥ 3.22 positions it relative to the window (`gtk_menu_popup_at_rect`, `src/gtk/window.cpp:6520-6565`), so it is safe |
|
||||
|
||||
@@ -540,7 +540,7 @@ The full Esc/close path is in `references/windows-dialogs.md`.
|
||||
layout"; specials are their `WXK_*` (`:1371-1394`). A Cyrillic `ц` gives `'W'`, so Ctrl+letter
|
||||
shortcuts work across layouts, but an AZERTY key reports its own label (`$` where US has `]`), so
|
||||
`Ctrl-;`-style punctuation accelerators may be untypeable on some layouts (`:1396-1407`). wxGTK
|
||||
got the non-Latin mapping in 3.3.0 (#23379, `docs/changes.txt:540`).
|
||||
got the non-Latin mapping in 3.3.0 (#23379, `docs/changes.txt:733`).
|
||||
- `wxEVT_CHAR` reflects Shift and the layout. Ctrl+letter gives 1..26 (`WXK_CONTROL_A` …,
|
||||
`:1409-1421`). Exception: on macOS Cmd+letter's CHAR is the letter itself (`'a'`/`'A'`); only the
|
||||
physical Control key yields 1..26 (`src/osx/cocoa/window.mm:304-307`).
|
||||
@@ -629,8 +629,14 @@ Space/Return holds the mouse capture until its KEY_UP reaches the button. On MSW
|
||||
|
||||
### Contract
|
||||
|
||||
- "An accelerator takes precedence over normal processing" (`interface/wx/accel.h:178`), but it
|
||||
runs after `wxEVT_CHAR_HOOK` on every port (table above).
|
||||
- "An accelerator takes precedence over normal processing" (`interface/wx/accel.h:178`). Since 3.3.4 this
|
||||
holds on every port (wxGTK used to let the focused window handle the key first), unless the focused
|
||||
window claims the key. The accelerator walk still runs after `wxEVT_CHAR_HOOK` (table above). The new
|
||||
`wxEVT_ACCELERATOR_KEY` event (`interface/wx/event.h:1740-1801`, `@since 3.3.4`) is sent to the focus
|
||||
window — and propagated to its parents — before an accelerator is used; it is sent after
|
||||
`wxEVT_CHAR_HOOK` on most ports and before it on macOS. Its handler can call `UseAccelerator()`, and a
|
||||
window that must keep the key overrides `wxWindow::ClaimsKeyBeforeAccelerator()`
|
||||
(`interface/wx/window.h:4554-4583`).
|
||||
- [source] On GTK and macOS a hit is sent as `wxEVT_MENU` with the entry's id and, if unprocessed,
|
||||
retried as `wxEVT_BUTTON`; macOS treats the key as consumed either way
|
||||
(`src/gtk/window.cpp:1340-1366`, `src/osx/window_osx.cpp:2563-2590`). On MSW the `WM_COMMAND` goes to
|
||||
@@ -654,11 +660,16 @@ Space/Return holds the mouse capture until its KEY_UP reaches the button. On MSW
|
||||
them in `wxMenuBar::RebuildAccelTable` (`src/msw/menu.cpp:1264-1292`); GTK adds the menu's accel
|
||||
group to the top-level window in `AttachToFrame` (`src/gtk/menu.cpp:239-247`). A menu shown with
|
||||
`PopupMenu` treats `"\tCtrl+X"` as display text.
|
||||
- **MSW:** accelerators are not translated while a `wxTextCtrl`/`wxComboBox`/`wxSpinCtrl` has focus and
|
||||
the key is a text-editing key: Ctrl+A/C/V/X/Ins/Del/Home/End/Left/Right, Shift+those navigation
|
||||
keys, bare Del/Home/End, Alt+Backspace (`src/msw/textentry.cpp:1073-1150`). Multi-line controls also
|
||||
keep Enter (`src/msw/textctrl.cpp:2110-2135`).
|
||||
- **GTK:** the accelerator walk has no such exemption (`src/gtk/window.cpp:1340-1366`). As menu
|
||||
- **Text-entry controls claim their editing keys on every port since 3.3.4.** A `wxTextCtrl`, a
|
||||
non-read-only `wxComboBox` or a `wxSpinCtrl` overrides `ClaimsKeyBeforeAccelerator()` to return
|
||||
`wxTextEntryBase::IsUsedForEditing()` (`src/common/textcmn.cpp:136-140`;
|
||||
`src/common/spinctrlcmn.cpp:160-167`; `src/msw/combobox.cpp:389-395`, `src/gtk/combobox.cpp:205-211`):
|
||||
Alt+Backspace; any printable key with no modifier or Shift (except Delete, so Esc/Enter/Tab stay
|
||||
usable); Backspace/Delete/Home/End with no modifier or Shift; Ctrl+A/C/V/X; and Insert/Delete/Home/
|
||||
End/Left/Right with Ctrl or Shift. A matching menu accelerator does not fire while such a control has
|
||||
focus. The set lives in `IsUsedForEditing` (`src/common/textentrycmn.cpp:441-509`).
|
||||
- **GTK:** the accelerator walk now consults `ClaimsKeyBeforeAccelerator()` too
|
||||
(`src/gtk/window.cpp:1524-1539`), so the text-control exemption above applies here since 3.3.4. As menu
|
||||
accelerators, Shift with non-alphabetic keys does not work, bare arrow keys do not work, and the
|
||||
listed keys (Tab, the modifiers, locks …) are unsupported (`interface/wx/menuitem.h:562-575`).
|
||||
- **macOS:** menu-bar items become `NSMenuItem` key equivalents
|
||||
|
||||
@@ -69,9 +69,12 @@ Contents: [The stack](#the-stack-orcas-gui-is-built-on) ·
|
||||
|
||||
## The stack Orca's GUI is built on
|
||||
|
||||
- **wxWidgets 3.3.2, SoftFever fork.** `deps/wxWidgets/wxWidgets.cmake` fetches
|
||||
`https://github.com/SoftFever/Orca-deps-wxWidgets` at tag `v3.3.2` and builds it static
|
||||
(`-DwxBUILD_SHARED=OFF`); Flatpak builds build it shared. Linux builds against **GTK3** by default
|
||||
- **wxWidgets 3.3.4, upstream.** `deps/wxWidgets/wxWidgets.cmake` fetches
|
||||
`https://github.com/wxWidgets/wxWidgets` at tag `v3.3.4` and builds it static
|
||||
(`-DwxBUILD_SHARED=OFF`); Flatpak builds build it shared. Two in-tree platform patches apply on
|
||||
Apple and Windows only (`0001-macos-use-srgb-colour-components.patch`,
|
||||
`0002-clang-cl-sibling-compiler-prefix.patch`) — `references/platforms.md`. Linux builds against
|
||||
**GTK3** by default
|
||||
(`option(DEP_WX_GTK3 "Build wxWidgets against GTK3" ON)` in `deps/CMakeLists.txt`, `SLIC3R_GTK`
|
||||
default `"3"`, Flatpak uses gtk3). GTK2 exists only as an opt-out (`-DDEP_WX_GTK3=OFF`) and loses
|
||||
EGL, WebKit2 and DIP pixels. Code guarded for GTK should still compile on GTK2, but GTK3 under X11
|
||||
@@ -85,11 +88,12 @@ Contents: [The stack](#the-stack-orcas-gui-is-built-on) ·
|
||||
- **Orca's own widget library.** New UI code largely does not use raw wx controls: the owner-drawn
|
||||
widgets in `src/slic3r/GUI/Widgets/` (`Button`, `CheckBox`, `ComboBox`, `TextInput`, `SpinInput`,
|
||||
`SwitchButton`, `RadioGroup`, `Label`, `DialogButtons`, …) replace them. Reasons: native controls
|
||||
cannot follow Orca's look or its app-level dark-mode toggle; on Windows wx's native dark mode does
|
||||
not reach anything built on `TaskDialog()` (`wxMessageBox`, `wxMessageDialog`, `wxRichMessageDialog`,
|
||||
`wxProgressDialog`) nor the wrapped common dialogs (`wxColourDialog`, `wxFontDialog`, …)
|
||||
(`interface/wx/app.h:1434-1443`), so Orca shows the `MsgDialog` family and its own generic
|
||||
`Widgets/ProgressDialog` instead; and on GTK the theme's borders bleed through wrapped native
|
||||
cannot follow Orca's look or its app-level dark-mode toggle; on Windows wx's native dark mode reaches
|
||||
the `TaskDialog()`-based boxes (`wxMessageBox`, `wxMessageDialog`, `wxRichMessageDialog`,
|
||||
`wxProgressDialog`) since 3.3.3 and the wrapped common dialogs (`wxColourDialog`, `wxFontDialog`, …)
|
||||
since 3.3.4, but the date/time/calendar controls, `wxPrintDialog` on Windows 10 and MDI applications
|
||||
stay light (`interface/wx/app.h:1442-1448`), so Orca shows the `MsgDialog` family and its own generic
|
||||
`Widgets/ProgressDialog` for a consistent look; and on GTK the theme's borders bleed through wrapped native
|
||||
controls (the widgets call `RemoveButtonBorder` / `RemoveInputBorder` under `__WXGTK__`).
|
||||
Plain containers stay raw (`wxPanel`, `wxBoxSizer`, `wxScrolledWindow`).
|
||||
- **Namespaces.** Most widgets are in the global namespace; a few (`DialogButtons`, `HyperLink`,
|
||||
|
||||
@@ -67,9 +67,10 @@ Contents: [Rules](#rules) · [Why the library exists](#why-the-library-exists)
|
||||
Native controls cannot carry Orca's flat, rounded, palette-coloured look, and they cannot follow all of Orca's
|
||||
theming:
|
||||
- On Windows the theme is an app-level setting (Preferences "Enable dark Mode", Windows-only) layered on
|
||||
`MSWEnableDarkMode`, and wx's MSW dark mode does not reach `TaskDialog()`-based dialogs (`wxMessageBox`,
|
||||
`wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`), the common dialogs or the date/time pickers
|
||||
(`interface/wx/app.h:1436-1445`). Hence the `MsgDialog` family (`references/windows-dialogs.md`) and Orca's own
|
||||
`MSWEnableDarkMode`; wx's MSW dark mode now reaches the `TaskDialog()`-based dialogs (`wxMessageBox`,
|
||||
`wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`) since 3.3.3 and the common dialogs since 3.3.4,
|
||||
but the date/time pickers, `wxPrintDialog` on Windows 10 and MDI applications stay light
|
||||
(`interface/wx/app.h:1442-1448`). Hence the `MsgDialog` family (`references/windows-dialogs.md`) and Orca's own
|
||||
`ProgressDialog`.
|
||||
- On macOS and Linux Orca follows the system appearance; native controls are themed by the toolkit, but any
|
||||
light palette colour set on them still needs the `UpdateDarkUI` pass (`references/colours-dark-mode.md`).
|
||||
|
||||
@@ -6,7 +6,7 @@ to write a custom control on the wx side and how to author an Orca widget on the
|
||||
`StaticBox`/`StateHandler` foundation. Read it before writing or reviewing any `wxEVT_PAINT`
|
||||
handler, `render`/`doRender` method, `messureSize`, or a new class under `src/slic3r/GUI/Widgets/`.
|
||||
|
||||
wx cites are relative to the pinned wx 3.3.2 tree (located as in `SKILL.md` §Ground truth).
|
||||
wx cites are relative to the pinned wx 3.3.4 tree (located as in `SKILL.md` §Ground truth).
|
||||
Orca builds wx with `wxBUILD_DEBUG_LEVEL=0` and `libslic3r_gui` with `wxDEBUG_LEVEL=0`: every
|
||||
wx assert below is compiled out and `wxCHECK*` returns silently, so paint misuse shows up only as
|
||||
wrong, missing or stale pixels, never as an assert dialog.
|
||||
@@ -116,7 +116,7 @@ Bind(wxEVT_PAINT, [this](wxPaintEvent&) {
|
||||
|
||||
| Situation | MSW | macOS | GTK3 (X11 and Wayland) | GTK2 (opt-out build) |
|
||||
|---|---|---|---|---|
|
||||
| Handler creates no `wxPaintDC` | `wxWindowMSW::HandlePaint` sees no DC and lets `DefWindowProc` validate the region: no `WM_PAINT` storm in 3.3.2, but drawing is unclipped and the contract is broken (`src/msw/window.cpp` `HandlePaint`) | no error; the window shows only what the background step left (undetermined under `wxBG_STYLE_PAINT`) | same | same |
|
||||
| Handler creates no `wxPaintDC` | `wxWindowMSW::HandlePaint` sees no DC and lets `DefWindowProc` validate the region: no `WM_PAINT` storm in 3.3.4, but drawing is unclipped and the contract is broken (`src/msw/window.cpp` `HandlePaint`) | no error; the window shows only what the background step left (undetermined under `wxBG_STYLE_PAINT`) | same | same |
|
||||
| Handler creates a DC, then `Skip()`s | default `OnPaint` (native painting) runs as well | — | — | — |
|
||||
| `wxPaintDC` outside a paint event | `wxCHECK_RET(!paintStack.empty(), "wxPaintDC can't be created outside wxEVT_PAINT handler")` (also for a window other than the one being repainted): the DC gets no HDC and every draw call is a silent no-op (`src/msw/dcclient.cpp` `wxPaintDCImpl::wxPaintDCImpl`) | no visible effect | `wxCHECK_RET(cr, "using wxPaintDC without being in a native paint event")`, every draw call is a silent no-op (`src/gtk/dc.cpp:518`) | works (GDK) |
|
||||
| `wxClientDC` drawing | works on non-composited windows; the doc lists "wxMSW when using double buffering" (`WS_EX_COMPOSITED`, see below) as non-working (`interface/wx/dcclient.h:82-84`), yet `CanBeUsedForDrawing` returns `true` unconditionally (`include/wx/msw/dcclient.h:60`), so it cannot detect that case | never; `CanBeUsedForDrawing` is `false` (`include/wx/osx/dcclient.h:58`) | X11 works; Wayland has no effect, `CanBeUsedForDrawing` is `false` on `wxDisplayWayland` (`src/gtk/dc.cpp` `wxClientDCImpl::CanBeUsedForDrawing`) | works |
|
||||
@@ -283,8 +283,8 @@ void MyCard::OnPaint(wxPaintEvent&) {
|
||||
ancestor up to the TLW (`src/msw/window.cpp` `wxWindowMSW::IsDoubleBuffered`);
|
||||
`SetDoubleBuffered(on)` toggles that style; `MSWDisableComposited()` removes it up the chain.
|
||||
`WS_EX_COMPOSITED` makes the whole subtree paint bottom-up into one buffer.
|
||||
- wx 3.3.0 enabled double buffering for all MSW windows (#22851, `docs/changes.txt:557`) and 3.3.2
|
||||
reverted it (#25808, `docs/changes.txt:308`). In 3.3.2 nothing in wx sets `WS_EX_COMPOSITED`
|
||||
- wx 3.3.0 enabled double buffering for all MSW windows (#22851, `docs/changes.txt:750`) and 3.3.2
|
||||
reverted it (#25808, `docs/changes.txt:501`). In 3.3.4 nothing in wx sets `WS_EX_COMPOSITED`
|
||||
unless the app calls `SetDoubleBuffered(true)`: MSW windows are not double-buffered by default,
|
||||
exactly as in 3.2.
|
||||
- macOS: always double-buffered, `IsDoubleBuffered()` returns `true` (`include/wx/osx/window.h:161`);
|
||||
@@ -439,7 +439,7 @@ Two variants exist:
|
||||
(`src/msw/gdiimage.cpp` `wxGDIImage::GetScaleFactor`, `src/msw/dcmemory.cpp`; details in
|
||||
`references/dpi-bitmaps-fonts.md §wxBitmap`), while `GetLogicalSize()` stays the physical size there.
|
||||
- MSW `wxBitmap::Create(size, dc)` no longer multiplies by the DC content scale; the size is
|
||||
physical (`docs/changes.txt:94-96`).
|
||||
physical (`docs/changes.txt:100-102`).
|
||||
|
||||
**Usage — portable back buffer.**
|
||||
```cpp
|
||||
@@ -556,7 +556,7 @@ already prepared ([Buffered painting](#buffered-painting-and-double-buffering)).
|
||||
must set the appropriate fonts and colours" (`interface/wx/dc.h:775-780`). `GetFont()` returns `wxNullFont` until
|
||||
`SetFont()` is called (`interface/wx/dc.h:715-720`).
|
||||
- wx 3.3 moved the non-drawing members to `wxReadOnlyDC` and several overridable measuring virtuals
|
||||
now take it (`docs/changes.txt:228-231`); see `references/wx-33-changes.md`.
|
||||
now take it (`docs/changes.txt:260-263`); see `references/wx-33-changes.md`.
|
||||
|
||||
**OrcaSlicer.** Orca widgets measure in `messureSize()`. A `messureSize()` that builds a
|
||||
`wxClientDC dc(this)` (`Button::messureSize`, `TextInput::messureSize`) measures correctly on every
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Platforms, the wx build, and platform-specific code
|
||||
|
||||
Read this when code has to differ per platform, when a bug shows up on only one OS, toolkit or display
|
||||
server, or when you need to know how Orca's wxWidgets is built. It covers the wx fork and its build
|
||||
server, or when you need to know how Orca's wxWidgets is built. It covers the wx source pin and its build
|
||||
options, platform macros, per-platform summaries that point into the topic files, and where
|
||||
platform-specific code lives. It also owns runtime X11/Wayland detection, the Wayland gap list, custom
|
||||
title bars and window decoration, GTK native-chrome removal, and the cross-platform test checklist.
|
||||
@@ -58,37 +58,46 @@ Contents: [Rules](#rules) · [The wx build Orca uses](#the-wx-build-orca-uses)
|
||||
|
||||
## The wx build Orca uses
|
||||
|
||||
### Source, pin and local patch
|
||||
### Source, pin and local patches
|
||||
|
||||
- `deps/wxWidgets/wxWidgets.cmake` builds `https://github.com/SoftFever/Orca-deps-wxWidgets` at tag
|
||||
**`v3.3.2`** (`GIT_SHALLOW ON`, submodules `3rdparty/catch`, `3rdparty/pcre` and `3rdparty/libwebp`
|
||||
only). The fork carries Orca's build fixes, the clang-cl fix among them; do not duplicate
|
||||
a fork fix as a local patch under `deps/wxWidgets/` (cc390f11ee removed the local
|
||||
`0001-Clang-CL-fix.patch` once the fork carried the fix). The fork's clang-cl fix is the MSVC lib-dir
|
||||
selection in the installed `wxWidgetsConfig.cmake`: it looks for `<prefix>_<arch>_lib` (or `_dll`)
|
||||
under the consuming compiler's prefix first and then the sibling one (`clang` ↔ `vc`), because cl
|
||||
and clang-cl share an ABI and either can consume either build
|
||||
(`build/cmake/wxWidgetsConfig.cmake.in:53-73`).
|
||||
- **The one local patch** is `deps/wxWidgets/0001-macos-use-srgb-colour-components.patch`, applied
|
||||
- `deps/wxWidgets/wxWidgets.cmake` builds upstream `https://github.com/wxWidgets/wxWidgets` at tag
|
||||
**`v3.3.4`** (`GIT_SHALLOW ON`, submodules `3rdparty/catch`, `3rdparty/pcre` and `3rdparty/libwebp`
|
||||
only). Two in-tree patches under `deps/wxWidgets/` are applied, one per platform, so neither applies
|
||||
on Linux: `0001-macos-use-srgb-colour-components.patch` on Apple and
|
||||
`0002-clang-cl-sibling-compiler-prefix.patch` on Windows. The clang-cl patch is the old fork's
|
||||
clang-cl fix ported back to a local patch: it changes the MSVC lib-dir selection in the installed
|
||||
`wxWidgetsConfig.cmake` so it looks for `<prefix>_<arch>_lib` (or `_dll`) under the consuming
|
||||
compiler's prefix first and then the sibling one (`clang` ↔ `vc`), because cl and clang-cl share an
|
||||
ABI and either can consume either build (`build/cmake/wxWidgetsConfig.cmake.in:53-73`). Because the
|
||||
pin is upstream, every other build fix must live as a local patch under `deps/wxWidgets/`.
|
||||
- **The Apple patch** is `deps/wxWidgets/0001-macos-use-srgb-colour-components.patch`, applied
|
||||
only `if (APPLE)`. The `PATCH_COMMAND` first runs `git checkout -f -- src/osx/cocoa/colour.mm` and
|
||||
then `git apply`, so the step can run again safely (a7775296b0). The patch makes the wxOSX
|
||||
`wxColour` component getters (`wxNSColorRefData::Red/Green/Blue/Alpha` and `IsSolid`) convert the
|
||||
`NSColor` with `[NSColorSpace sRGBColorSpace]` instead of `NSCalibratedRGBColorSpace`, so colours
|
||||
read back on macOS match their sRGB values (custom-colour accuracy). Colour usage:
|
||||
`references/colours-dark-mode.md`.
|
||||
- **The Windows patch** is `deps/wxWidgets/0002-clang-cl-sibling-compiler-prefix.patch`, applied only
|
||||
`if (WIN32)`. Its `PATCH_COMMAND` first runs
|
||||
`git checkout -f -- build/cmake/wxWidgetsConfig.cmake.in` and then `git apply`, so the step can run
|
||||
again safely. It rewrites the `WIN32_MSVC_NAMING` branch of `build/cmake/wxWidgetsConfig.cmake.in`
|
||||
to try the consuming compiler's prefix first and then the sibling one (`clang` ↔ `vc`) when locating
|
||||
the installed `<prefix>_<arch>_lib`/`_dll` directory.
|
||||
- The checked-out source is the tree that every wx citation in this skill refers to:
|
||||
`deps/build/<arch>/dep_wxWidgets-prefix/src/dep_wxWidgets` on macOS and
|
||||
`deps/<tree>/dep_wxWidgets-prefix/src/dep_wxWidgets` on Linux and Windows (`deps/build` for a
|
||||
release build; `build_win.bat` names the others). Locate it with the bash or PowerShell lookup in
|
||||
`SKILL.md` §Ground truth. On macOS its
|
||||
`src/osx/cocoa/colour.mm` already has the patch applied.
|
||||
`src/osx/cocoa/colour.mm` already has the Apple patch applied; on Windows its
|
||||
`build/cmake/wxWidgetsConfig.cmake.in` already has the clang-cl patch applied.
|
||||
- **Flatpak builds wx separately.** `deps/CMakeLists.txt` leaves `dep_wxWidgets` out of the deps
|
||||
target when `FLATPAK` is set. Instead, `scripts/flatpak/com.orcaslicer.OrcaSlicer.yml` has its own
|
||||
`wxWidgets` module whose config-opts "mirror deps/wxWidgets/wxWidgets.cmake with FLATPAK=ON,
|
||||
DEP_WX_GTK3=ON": `-DwxBUILD_TOOLKIT=gtk3`, a shared build (`wxBUILD_SHARED=ON`,
|
||||
`BUILD_SHARED_LIBS=ON`, `d` debug postfix), and `wxUSE_LIBWEBP=sys`, because the builtin webp
|
||||
libraries are installed only by static builds. It links with lld and pins the fork's tag
|
||||
`orca-3.3.2` at a fixed commit. Option and version changes must be made in both files.
|
||||
libraries are installed only by static builds. It links with lld and pins upstream `v3.3.4` at
|
||||
commit `6a42a4b999b127cf28a8b5fe686da6b8ca93a9b8`. Option and version changes must be made in both
|
||||
files; it applies neither patch (GTK3, no MSVC).
|
||||
|
||||
### Toolkit per platform
|
||||
|
||||
@@ -188,7 +197,7 @@ Its `wx/gtk/private*` includes are commented out. The per-port headers outside t
|
||||
`wx/msw/private.h` (`BitmapComboBox.cpp`, `PresetComboBoxes.cpp`, Windows-guarded) and
|
||||
`wx/osx/private.h` (`Utils/MacDarkMode.mm`), come with the regular wx install. Private headers are
|
||||
port-specific and unversioned. Include one only under the same macro wx uses for that port or
|
||||
feature, and re-check it whenever the fork is bumped.
|
||||
feature, and re-check it whenever the wx pin is bumped.
|
||||
|
||||
### wxInspector
|
||||
|
||||
@@ -268,8 +277,8 @@ Each bullet names the mechanism and the file that owns it.
|
||||
popups with it are dismissed on deactivation, deferred through `CallAfter`. No key dismisses a
|
||||
popup, and `ProcessLeftDown` is never called. `PopupWindow::BindUnfocusEvent` is MSW-only →
|
||||
`references/popups-menus.md` §5.
|
||||
- **Painting:** in 3.3.2 windows are not double-buffered by default (the 3.3.0 global
|
||||
`WS_EX_COMPOSITED` was reverted, `docs/changes.txt:308`). Custom widgets buffer by hand →
|
||||
- **Painting:** in 3.3.4 windows are not double-buffered by default (the 3.3.0 global
|
||||
`WS_EX_COMPOSITED` was reverted, `docs/changes.txt:501`). Custom widgets buffer by hand →
|
||||
`references/painting-custom-widgets.md`.
|
||||
- **Building large panels:** every control is a native child window, and outside a sizer pass a move
|
||||
or resize is immediate, repainting when the window is shown [source: `src/msw/window.cpp:2036`
|
||||
@@ -284,8 +293,9 @@ Each bullet names the mechanism and the file that owns it.
|
||||
- **Mouse capture:** `wxEVT_MOUSE_CAPTURE_LOST` and `wxEVT_MOUSE_CAPTURE_CHANGED` are delivered →
|
||||
`references/mouse-keyboard-focus.md`.
|
||||
- **Controls:** `wxDataViewCtrl` is the generic implementation (`references/controls-dataview.md`).
|
||||
TaskDialog-based dialogs and common dialogs stay light in wx dark mode
|
||||
(`interface/wx/app.h:1434-1448`); Orca's `MsgDialog` family is owner-drawn →
|
||||
TaskDialog-based dialogs (since 3.3.3) and common dialogs (since 3.3.4) follow wx dark mode; the
|
||||
date/time/calendar controls, `wxPrintDialog` on Windows 10 and MDI applications stay light
|
||||
(`interface/wx/app.h:1442-1448`); Orca's `MsgDialog` family is owner-drawn →
|
||||
`references/windows-dialogs.md`.
|
||||
- **WebView:** Edge (WebView2). It needs the runtime (checked by `GUI_App::init_webview_runtime`),
|
||||
creates asynchronously, serves custom schemes as `https://<scheme>.wxsite`, and allows one script
|
||||
@@ -616,16 +626,16 @@ headers. Rows marked [source] or "protocol" come from the implementation or from
|
||||
| Area | What happens on Wayland | Cite | Orca handling / owner |
|
||||
|---|---|---|---|
|
||||
| Global pointer position | `wxGetMousePosition()` / `wxGetMouseState()` call `gdk_device_get_position` [source], but Wayland gives clients no global pointer position, so the result is not a screen position | `src/gtk/window.cpp` `wxGetMousePosition` | use event coordinates + `ClientToScreen` (`BBLTopbar`); dismiss popups by focus tracking (`SearchDialog::Dismiss`) → `references/mouse-keyboard-focus.md` |
|
||||
| Top-level position | the compositor places windows, and `SetPosition()` / `Move()` on a TLW have no effect (protocol) | — | `GUI_App::window_pos_restore` restores only size and maximised state; moves go through `gtk_window_begin_move_drag` |
|
||||
| Top-level position | the compositor places windows, and `SetPosition()` / `Move()` on a TLW have no effect (protocol). 3.3.4 added geometry restore through the Wayland XDG session-management protocol (`SaveGeometry`/`RestoreToGeometry` with the new `SaveString`/`RestoreString` fields) | `interface/wx/toplevel.h:439-455, 474-490` | `GUI_App::window_pos_restore` restores only size and maximised state; moves go through `gtk_window_begin_move_drag` |
|
||||
| Window icon | `SetIcon()` / `SetIcons()` "doesn't do anything when using Wayland … create a `.desktop` file" | `interface/wx/toplevel.h:517-521, 538-542` | `src/dev-utils/platform/unix/com.orcaslicer.OrcaSlicer.desktop` (`Icon=OrcaSlicer`, `StartupWMClass=orca-slicer`) |
|
||||
| App id | `wxAppConsole::SetClassName()` is the xdg `app_id` with GTK ≥ 3.24.22 (and the AUMID on Windows); it must be set before any TLW. wx applies it when a TLW is mapped, and only if it is non-empty [source: `wxTopLevelWindowGTK::GTKHandleMapped`] | `interface/wx/app.h:765-812` | Orca calls only `SetAppName(SLIC3R_APP_KEY)`, so GTK's default applies. On Windows, `SetClassName` would also change shell behaviour (MRU, Shift+middle-click) |
|
||||
| `wxClientDC` | deprecated in 3.3 ("please use wxInfoDC instead for obtaining information", `interface/wx/dcclient.h:43-46`). Drawing through it "simply doesn't have any effect" on GTK3/Wayland or wxOSX. `CanBeUsedForDrawing()` [source]: false on Wayland only for wxGTK (`src/gtk/dc.cpp`), always false on wxOSX, always true on wxMSW (`include/wx/{osx,msw}/dcclient.h`), although its doc also lists "wxMSW when using double buffering" | `interface/wx/dcclient.h:48-53, 80-88` | draw only in `wxPaintDC` after `Refresh()`/`RefreshRect()` → `references/painting-custom-widgets.md` |
|
||||
| `wxWindow::Update()` | "doesn't do anything in wxGTK port when using Wayland". [source] wx skips the GDK update calls there because they broke later updates (#25036) | `interface/wx/window.h:2405-2407` | never rely on `Update()` to paint synchronously |
|
||||
| `WarpPointer()` | works only if the compositor implements the pointer-warp protocol; mutter also needs a mouse button held | `interface/wx/window.h:3902-3907`; `docs/changes.txt:294` | Orca never warps the pointer |
|
||||
| `WarpPointer()` | works only if the compositor implements the pointer-warp protocol; mutter also needs a mouse button held | `interface/wx/window.h:3902-3907`; `docs/changes.txt:487` | Orca never warps the pointer |
|
||||
| `wxUIActionSimulator` | "currently doesn't work when using Wayland with wxGTK" | `interface/wx/uiaction.h:20` | not used; Orca also builds `wxUSE_XTEST=OFF` |
|
||||
| `wxBitmap(const wxCursor&)` | creates an invalid bitmap | `interface/wx/bitmap.h:393-395` | — |
|
||||
| OpenGL | only EGL; `PreferGLX()` has no effect. Without EGL in the build, wxGTK's `wxGLCanvas` shows a fatal message and refuses to work [source: `src/gtk/glcanvas.cpp` `IsAvailable`]. The EGL surface is a subsurface over the canvas, ready only after map and a frame callback [source: `src/unix/glegl.cpp`] | `interface/wx/glcanvas.h:1094-1095` | `CLI::run` forces X11 when wx lacks EGL; overlays are drawn in GL/ImGui, never as wx children over the canvas → `references/webview-gl-aui-media.md` |
|
||||
| AUI | the doc note "live resize is always used … for wxOSX and wxGTK3 when using Wayland" is obsolete: "As of wxWidgets 3.3.0 this function always returns false", and `wxAUI_MGR_LIVE_RESIZE` is in the default flags. Floating panes need global positions | `interface/wx/aui/framemanager.h:336-345` | `Plater::priv::priv` clears `wxAUI_MGR_ALLOW_FLOATING`; `sanitize_window_layout_for_wayland` strips floating state from the saved layout → `references/webview-gl-aui-media.md` §wxAuiManager |
|
||||
| AUI | the doc note "live resize is always used … for wxOSX and wxGTK3 when using Wayland" is obsolete: "As of wxWidgets 3.3.0 this function always returns false", and `wxAUI_MGR_LIVE_RESIZE` is in the default flags. AUI's docking-hint logic still needs global positions; 3.3.4 added system drag sessions (`StartDragSession`) so wx can move a pane's floating frame under Wayland anyway | `interface/wx/aui/framemanager.h:336-345`; `src/aui/framemanager.cpp:4574-4599` | `Plater::priv::priv` clears `wxAUI_MGR_ALLOW_FLOATING`; `sanitize_window_layout_for_wayland` strips floating state from the saved layout → `references/webview-gl-aui-media.md` §wxAuiManager |
|
||||
| Popups | a GTK popup is an `xdg_popup` only for COMBO/DROPDOWN/POPUP_MENU hints, so wx creates popups with `GDK_WINDOW_TYPE_HINT_COMBO` [source]. A chained popup's parent must be the mapped popup, and mapping it with a grab deactivates the toplevel (Orca's comments in `DropDown::mouseMove`, `DropDown::ShouldDismissOnTopWindowDeactivate`) | `src/gtk/popupwin.cpp:110-114` | `DropDown` transient-for chain, `ShouldDismissOnTopWindowDeactivate` → `references/popups-menus.md` |
|
||||
| Fractional scale | arrives as an integer GDK scale | `docs/doxygen/overviews/high_dpi.md:348-351` | → `references/dpi-bitmaps-fonts.md` |
|
||||
| Window decorations | some desktop environments draw a title bar on undecorated windows anyway | — | [Undecorated windows](#wayland-undecorated-top-level-windows-splash) |
|
||||
@@ -636,7 +646,9 @@ were two-finger scrolling (703, 3.1.3), the EGL-based `wxGLCanvas` for Wayland (
|
||||
support (498, both 3.1.5). New with the upgrade: "Many bug fixes for Wayland-specific problem" (397)
|
||||
and a `wxMediaCtrl` fix (402) in 3.1.6, GDK errors from `PopupMenu()` avoided (317, 3.1.7),
|
||||
`wxCURSOR_SIZING` fixed (261, 3.2.0). In 3.3, `WarpPointer()` on supported compositors
|
||||
(`docs/changes.txt:294`) and the EGL/Wayland high-DPI scale fix (`changes.txt:538`).
|
||||
(`docs/changes.txt:487`) and the EGL/Wayland high-DPI scale fix (`changes.txt:731`); in 3.3.4, a fix for
|
||||
the crash on pointer/seat disconnect (`changes.txt:371`), AUI pane dragging via system drag sessions
|
||||
(`:372`) and window-geometry restore via XDG session management (`:373`).
|
||||
|
||||
## Window decoration and custom title bars
|
||||
|
||||
@@ -658,7 +670,7 @@ There is no `wxCAPTION` on any platform; each port then needs its own handling.
|
||||
**Contract** [source + documented]. Since wx **3.3.0**, `wxTopLevelWindowMSW::MSWGetStyle` adds
|
||||
`WS_CAPTION` whenever any of `wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX` is set
|
||||
(`src/msw/toplevel.cpp:133-135`). The 3.3.0 wxMSW change list says "Turn wxCAPTION on automatically if
|
||||
required by other styles (#23575)" (`docs/changes.txt:581`). Commit eefdabcd98 attributes this to
|
||||
required by other styles (#23575)" (`docs/changes.txt:774`). Commit eefdabcd98 attributes this to
|
||||
3.3.2, but it is a 3.3.0 change. `SetWindowStyleFlag()` recomputes the native style through
|
||||
`MSWGetStyle` and turns the bits back on (`src/msw/window.cpp` `wxWindowMSW::MSWUpdateStyle`).
|
||||
|
||||
@@ -868,10 +880,11 @@ do both). Cite: 6148ba16b3, 988b500f33.
|
||||
|
||||
## wx 3.3 migration notes
|
||||
|
||||
Orca moved from **3.1.5** to 3.3.2 in 8248b06337 ("Updated wxWidgets to 3.3.2", #12941; build system
|
||||
in 2d7e26292b), so the 3.1.6–3.2.0 incompatible changes (`docs/changes_32.txt`) apply as well as
|
||||
`docs/changes.txt`. The version digest, every migration commit as a rule for new code, and the
|
||||
post-upgrade regressions to watch are owned by `references/wx-33-changes.md` (§8). The
|
||||
Orca moved from **3.1.5** to **3.3.2** in 8248b06337 ("Updated wxWidgets to 3.3.2", #12941; build system
|
||||
in 2d7e26292b); the pin is now upstream **3.3.4** (`deps/wxWidgets/wxWidgets.cmake`, tag `v3.3.4`), so
|
||||
the 3.1.6–3.2.0 incompatible changes (`docs/changes_32.txt`) apply as well as `docs/changes.txt`. The
|
||||
version digest, every migration commit as a rule for new code, and the post-upgrade regressions to
|
||||
watch are owned by `references/wx-33-changes.md` (§10); the 3.3.3 and 3.3.4 changes are its §8–§9. The
|
||||
platform-specific ones are described in this file: the `MainFrame` `WS_CAPTION` handling
|
||||
([MSW title bar](#msw-the-mainframe-custom-title-bar)), the macOS `kAEGetURL` re-registration and the
|
||||
`SidePopup` anchoring ([ifdef landscape](#the-ifdef-landscape)), and the GTK criticals filter
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Popups, transient windows and menus
|
||||
|
||||
How wx 3.3.2 popups and menus behave on each port, and the Orca wrappers built on them: `PopupWindow`,
|
||||
How wx 3.3.4 popups and menus behave on each port, and the Orca wrappers built on them: `PopupWindow`,
|
||||
`DropDown`/`ComboBox`, `SidePopup`, the search popups, frameless dialogs used as popups, `MenuFactory`,
|
||||
`append_menu_item`, `Plater::PopupMenu` and the macOS menubar versus `BBLTopbar`. Read it before you add
|
||||
or change anything that opens over other UI and must close by itself, or any context menu or menubar item.
|
||||
@@ -791,7 +791,7 @@ created with `wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT | wxF
|
||||
`wxWindow`. "The window automatically destroys itself when the user clicks on it or it loses the focus"
|
||||
(`interface/wx/tipwin.h:13-14`). Since 3.3.2 use `static Ref New(parent, text, maxLength, rectBound)`. The
|
||||
returned `wxTipWindow::Ref` is "guaranteed to become invalid when the tip window is closed", and the raw
|
||||
constructor is deprecated (`tipwin.h:27-132`; `docs/changes.txt:286`). `Create` positions the tip at the mouse
|
||||
constructor is deprecated (`tipwin.h:27-132`; `docs/changes.txt:479`). `Create` positions the tip at the mouse
|
||||
and pops it up immediately (`src/generic/tipwin.cpp:171-240`); on GTK it also captures the mouse.
|
||||
`SetBoundingRect` closes the tip when the mouse leaves that rectangle (`tipwin.h:160-172`). Orca:
|
||||
`Button::OnParentMotion` (MSW-only tooltips for disabled buttons) keeps a `wxTipWindow::Ref`.
|
||||
@@ -800,11 +800,11 @@ created with `wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT | wxF
|
||||
`wxRichToolTipPopup` (`src/generic/richtooltipg.cpp`). Re-check it on every wx update.
|
||||
- **`wxInfoBar`** "calls its parent wxWindow::Layout() method and assumes that it will change the parent
|
||||
layout": add it to the parent's sizer (`interface/wx/infobar.h:38-44`). It is generic on all ports and native
|
||||
in wxGTK. Use `ShowMessage(msg, flags)`/`Dismiss()`. 3.3 adds `ShowCheckBox` (`docs/changes.txt:460`).
|
||||
in wxGTK. Use `ShowMessage(msg, flags)`/`Dismiss()`. 3.3 adds `ShowCheckBox` (`docs/changes.txt:653`).
|
||||
- **`wxNotificationMessage`** is "not a window", native on MSW, macOS and GTK (`interface/wx/notifmsg.h:12-18`).
|
||||
MSW recommends `MSWUseToasts()` before the first notification, macOS needs the alert notification style for
|
||||
actions, and GTK ignores the timeout for warnings and errors (`notifmsg.h:23-38`, 179-182). 3.3 reports the
|
||||
dismissal reason (`docs/changes.txt:488`). Orca does not use it. Its in-app notifications are the GL-canvas
|
||||
dismissal reason (`docs/changes.txt:681`). Orca does not use it. Its in-app notifications are the GL-canvas
|
||||
`NotificationManager`.
|
||||
|
||||
## 13. wxMenu and wxMenuItem
|
||||
@@ -862,7 +862,7 @@ submenu (it leaks), `Destroy(id)` deletes it, and `Remove()` returns ownership (
|
||||
an item switch it to owner-drawn (`MSWMustUseOwnerDrawn`, `src/msw/menuitem.cpp:1371-1377`). "Owner drawn items
|
||||
are also incompatible with dark mode support and using them makes the entire menu containing them to use
|
||||
standard light mode colours even in dark mode." 3.3.2 reworked MSW dark-mode menu rendering
|
||||
(`docs/changes.txt:305-306`); owner-drawn items still opt out of it.
|
||||
(`docs/changes.txt:498-499`); owner-drawn items still opt out of it.
|
||||
|
||||
**Labels and accelerators** (`menuitem.h:460-490`, 555-570).
|
||||
- The syntax is `"&Label\tCtrl+X"`; `&&` is a literal ampersand. `CTRL` means Cmd on macOS, and `RAWCTRL` gives
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Sizers and layout
|
||||
|
||||
How wx 3.3.2 computes window sizes and lays out children, and how OrcaSlicer builds layouts on top of
|
||||
How wx 3.3.4 computes window sizes and lays out children, and how OrcaSlicer builds layouts on top of
|
||||
that: sizers and flags, best/min size, the fitting functions (`SetSizerAndFit`, `SetSizeHints`, `Fit`,
|
||||
`Layout`, `FitInside`) per platform, show/hide relayout, Freeze/Thaw, scrolled windows, `wxStaticText`
|
||||
wrapping, layout on DPI change, and Orca's layout idioms. Read it when building or reviewing any dialog
|
||||
@@ -604,7 +604,7 @@ Ordinary dialogs and the sidebar use plain `wxScrolledWindow`.
|
||||
without spaces never wraps with `wxStaticText::Wrap`.
|
||||
- `wxST_WRAP` (new in 3.3.2): "Wrap label text on multiple lines if necessary, using the available
|
||||
horizontal space. This style only works when the control is used inside a sizer"
|
||||
(`interface/wx/stattext.h:46-49`; `docs/changes.txt:280`). It is opt-in; labels without it are
|
||||
(`interface/wx/stattext.h:46-49`; `docs/changes.txt:473`). It is opt-in; labels without it are
|
||||
unaffected. It is implemented with `GetMinSizeFromKnownDirection` (`stattextcmn.cpp:285-312`).
|
||||
**[source]** The initial `CalcMin` still uses the unwrapped best size, so a fitted dialog grows to the
|
||||
full one-line width and nothing wraps; constrain the width another way (a fixed or min width on the
|
||||
|
||||
@@ -44,7 +44,8 @@ Contents: [Rules](#rules) · [Build facts](#build-facts-that-decide-string-behav
|
||||
12. One complete sentence per msgid, placeholders instead of concatenated fragments, the number
|
||||
placeholder in both plural forms, `// TRN` for ambiguous strings, a context for homonyms.
|
||||
→ §Plurals and contexts
|
||||
13. A wrapper around `wxGetTranslation` returns `wxString` by value. → §Translation
|
||||
13. A wrapper that converts a translation (`wxString::FromUTF8`, `ToUTF8()`, `format_wxstr`) returns
|
||||
by value; `wxGetTranslation()` itself returns `const wxString&`. → §Translation
|
||||
14. User-supplied text (preset, filament, file, printer names) in a mnemonic-interpreting label
|
||||
goes through `SetLabelText` or `wxControl::EscapeMnemonics`. → §Labels
|
||||
15. File dialogs: filters from `file_wildcards(FT_*)`, default dir `from_u8(app_config->get_last_dir())`,
|
||||
@@ -186,11 +187,11 @@ was the splash screen's event filter, fixed in 4088a36095; see `references/threa
|
||||
**modifies the string**. Use `s[n].GetValue()` or an explicit `int`/`wchar_t` type
|
||||
(`interface/wx/string.h:171-226`).
|
||||
- Since 3.3 `wxstr = {"Hello", 2}` is ambiguous (the `string_view` constructor); write
|
||||
`wxString{"Hello", 2}` (`docs/changes.txt:191-194`).
|
||||
`wxString{"Hello", 2}` (`docs/changes.txt:223-226`).
|
||||
- Never pass a `wxString`, `c_str()` or `mb_str()` to a real C vararg function (`printf`); use
|
||||
`wxString::Format`/`wxPrintf` or convert explicitly (`interface/wx/string.h:262-300`).
|
||||
- `wxUSE_STL` no longer exists; wx 3.3 re-enables implicit `wxString` → `std::string` only through
|
||||
`wxUSE_STD_STRING_CONV_IN_WXSTRING=1` (`docs/changes.txt:163-166`). Orca keeps it 0 and adds
|
||||
`wxUSE_STD_STRING_CONV_IN_WXSTRING=1` (`docs/changes.txt:195-198`). Orca keeps it 0 and adds
|
||||
`wxNO_UNSAFE_WXSTRING_CONV`; do not enable either conversion, the compile error is the guard.
|
||||
|
||||
### Pitfalls
|
||||
@@ -322,10 +323,13 @@ language's decimal separator; `wxString::ToCDouble`/`FromCDouble` do not.
|
||||
**wx contract** (`interface/wx/translation.h:577-640`): `wxGetTranslation(string, domain = "",
|
||||
context = "")` returns the original string when no catalog has it; a non-empty context needs a
|
||||
matching `msgctxt` in the catalog; the plural overload returns `string` for `n == 1` and `plural`
|
||||
otherwise when no catalog is found; "This function is thread-safe". Since 3.3 it returns
|
||||
**`wxString` by value**, not a const reference: "please change the return type of the function to
|
||||
wxString" (`docs/changes.txt:139-142`). Orca's `I18N::translate` overloads already return by value;
|
||||
keep any new wrapper that way, a `const wxString&` return now dangles.
|
||||
otherwise when no catalog is found; "This function is thread-safe". It returns **`const wxString&`**
|
||||
(`interface/wx/translation.h:615`; `include/wx/translation.h:277-309`). 3.3.2 changed this to a
|
||||
by-value `wxString` and **3.3.3 reverted it** to the 3.2.x reference, so the reference points at the
|
||||
catalog's own string or at `wxTranslations::GetUntranslatedString()`, both of which outlive the call.
|
||||
Forwarding that reference is therefore safe; what must return by value is a wrapper that constructs a
|
||||
temporary — `wxString::FromUTF8`, `ToUTF8()`, `format_wxstr`. Orca's `I18N::translate` overloads
|
||||
return `wxString` by value and `translate_utf8`/`_u8L` return `std::string`.
|
||||
|
||||
**OrcaSlicer macros** (`src/slic3r/GUI/I18N.hpp`):
|
||||
|
||||
@@ -429,7 +433,7 @@ using this class doesn't affect the native controls and dialogs", and on macOS 1
|
||||
C locale can break the menus (`interface/wx/intl.h:282-292`): native file dialogs, the app menu and
|
||||
standard buttons follow the system language. `wxLocale::IsAvailable` builds a region tag and asks
|
||||
`wxUILocale(...).IsSupported()` (`src/common/intl.cpp` `wxLocale::IsAvailable`), which on Unix no
|
||||
longer falls back to another region of the same language (`docs/changes.txt:75-79`); keep the
|
||||
longer falls back to another region of the same language (`docs/changes.txt:81-85`); keep the
|
||||
fallbacks in `load_language`.
|
||||
|
||||
- **Rule:** translate at use; never store a translated string in a namespace-scope or function-local
|
||||
@@ -457,7 +461,7 @@ call `SetLabel(label)`) [source]. `SetLabelMarkup` also treats an
|
||||
unescaped `&` as a mnemonic, needs `&`/`<` for literal characters, strips the markup where it
|
||||
is unsupported, and leaves the label unchanged (returns false) when the string is not well-formed
|
||||
(`interface/wx/control.h:200-360`); user text inside markup must be XML-escaped.
|
||||
Since 3.3 wxListbook/wxChoicebook also interpret mnemonics in page titles (`docs/changes.txt:128-130`);
|
||||
Since 3.3 wxListbook/wxChoicebook also interpret mnemonics in page titles (`docs/changes.txt:134-136`);
|
||||
Orca uses neither, but the rule is the same for every book control.
|
||||
|
||||
**OrcaSlicer.** `Label` (`Widgets/Label.cpp`) derives from `wxStaticText`; `Label::SetLabel` stores
|
||||
@@ -495,7 +499,7 @@ so build it from the wide form (`into_path(w).wstring()`) or stay with boost. At
|
||||
expands `$VAR`/`%VAR%` inside file names (`interface/wx/filename.h:90-103`); use `MakeAbsolute()` or
|
||||
explicit `wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE`. 3.3 adds `IsMSWExtendedLengthPath()` for `\\?\`
|
||||
paths "avoiding the 260 character path length restriction" (`interface/wx/filename.h:1040-1051`,
|
||||
`docs/changes.txt:551`). `wxFileSystem::FileNameToURL`/`URLToFileName` convert to and from `file:`
|
||||
`docs/changes.txt:744`). `wxFileSystem::FileNameToURL`/`URLToFileName` convert to and from `file:`
|
||||
URLs (`interface/wx/filesys.h:96-103, 175-180`).
|
||||
|
||||
**`wxStandardPaths`** (`interface/wx/stdpaths.h`): the directories "may or may not exist"
|
||||
@@ -552,9 +556,9 @@ for (const wxString& p : paths)
|
||||
|
||||
| | Behaviour |
|
||||
|---|---|
|
||||
| MSW | New-style `IFileDialog`: wx calls `SetDefaultExtension` with the selected filter's first extension and no longer calls `AppendExtension` itself (`src/msw/filedlg.cpp:1644-1656, 1738-1740`; `docs/changes.txt:556`). `SetExtraControlCreator` → XP-style dialog. |
|
||||
| MSW | New-style `IFileDialog`: wx calls `SetDefaultExtension` with the selected filter's first extension and no longer calls `AppendExtension` itself (`src/msw/filedlg.cpp:1644-1656, 1738-1740`; `docs/changes.txt:749`). `SetExtraControlCreator` → XP-style dialog. |
|
||||
| macOS | Open dialogs show **no filter choice** and apply all wildcards at once unless `wxSystemOptions::SetOption(wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1)`, and even then non-matching files are only greyed (`interface/wx/filedlg.h:117-128`). Matching compares the lower-cased last path extension (`wxOpenSavePanelDelegate panel:shouldEnableURL:`, `src/osx/cocoa/filedlg.mm:58-88`) [source]: case-insensitive, and a multi-dot pattern such as `*.gcode.3mf` or `*.zip.amf` never matches by itself. `wxFD_OVERWRITE_PROMPT` is always on (`:172-175`); `wxFD_OPEN` always behaves as `wxFD_FILE_MUST_EXIST` (`:184-189`). The save panel replaces the initial file name's extension with the first one in the wildcard (Orca's comment on `file_wildcards`). The native panel runs `runModal` and does not re-raise the parent dialog afterwards (`src/osx/cocoa/filedlg.mm` `ShowModal`); see `references/windows-dialogs.md` for the deferred re-raise. |
|
||||
| GTK3 | `GtkFileChooserNative` (portal-capable, e.g. Flatpak) when GTK ≥ 3.20 at runtime and neither `wxFD_PREVIEW` nor an extra control/customize hook is used (`src/gtk/filedlg.cpp:265-274, 437-443`; `src/gtk/dirdlg.cpp:122-130`; `docs/changes.txt:393`). It runs through `gtk_native_dialog_run`: there is no wx window, so size/position calls do nothing (`wxFileDialog::DoSetSize` is empty). Patterns go to `gtk_file_filter_add_pattern` per token and are **case-sensitive** (`src/gtk/filectrl.cpp:169`). The chooser is transient for the parent left after `GetParentForModalDialog`, which replaces a null (or hidden, dying or `wxWS_EX_TRANSIENT`) parent with the active top-level window, else the app's main top window (`src/gtk/filedlg.cpp:206, 223-225`; `src/common/dlgcmn.cpp:180-203` `DoGetParentForDialog`) [source]. `wxFD_PREVIEW` is GTK-only (`interface/wx/filedlg.h:195-197`). |
|
||||
| GTK3 | `GtkFileChooserNative` (portal-capable, e.g. Flatpak) when GTK ≥ 3.20 at runtime and neither `wxFD_PREVIEW` nor an extra control/customize hook is used (`src/gtk/filedlg.cpp:265-274, 437-443`; `src/gtk/dirdlg.cpp:122-130`; `docs/changes.txt:586`). It runs through `gtk_native_dialog_run`: there is no wx window, so size/position calls do nothing (`wxFileDialog::DoSetSize` is empty). Patterns go to `gtk_file_filter_add_pattern` per token and are **case-sensitive** (`src/gtk/filectrl.cpp:169`). The chooser is transient for the parent left after `GetParentForModalDialog`, which replaces a null (or hidden, dying or `wxWS_EX_TRANSIENT`) parent with the active top-level window, else the app's main top window (`src/gtk/filedlg.cpp:206, 223-225`; `src/common/dlgcmn.cpp:180-203` `DoGetParentForDialog`) [source]. `wxFD_PREVIEW` is GTK-only (`interface/wx/filedlg.h:195-197`). |
|
||||
| GTK2 (opt-out build) | never uses the native chooser; patterns case-sensitive. |
|
||||
|
||||
**OrcaSlicer:**
|
||||
@@ -650,7 +654,7 @@ dtor, and `!lock` tests `IsOpened()`.
|
||||
|
||||
| | Behaviour |
|
||||
|---|---|
|
||||
| MSW | `SetData`/`GetData` do not check `Open()` (`src/msw/clipbrd.cpp` `wxClipboard::SetData`), so code that forgets it works here only. `wxTextDataObject::SetData()` size must now include the 2-byte NUL (`docs/changes.txt:62-66`); use `SetText()` or the ctor. |
|
||||
| MSW | `SetData`/`GetData` do not check `Open()` (`src/msw/clipbrd.cpp` `wxClipboard::SetData`), so code that forgets it works here only. `wxTextDataObject::SetData()` size must now include the 2-byte NUL (`docs/changes.txt:68-72`); use `SetText()` or the ctor. |
|
||||
| macOS | without `Open()`, `SetData`/`AddData`/`GetData` return false through `wxCHECK_MSG(m_open, …)` without taking the object (`src/osx/carbon/clipbrd.cpp:84-105, 140-147`); a successful write is flushed to the pasteboard immediately (`:110-114`). |
|
||||
| GTK | same `wxCHECK_MSG(m_open, …)` early return (`src/gtk/clipbrd.cpp:643-647, 775`). `GetData`/`IsSupported` are asynchronous underneath: `wxClipboardSync` spins `YieldFor(wxEVT_CATEGORY_CLIPBOARD)` until GTK answers and forbids re-entrancy (`src/gtk/clipbrd.cpp:68-92`). PRIMARY selection exists. Under Wayland, Wayland MIME types are advertised next to the X11 atoms (`src/gtk/clipbrd.cpp:655-700`). |
|
||||
|
||||
@@ -793,8 +797,8 @@ from a non-main thread on wxOSX (`:39-40`); `wxCANCEL_DEFAULT` is ignored on wxO
|
||||
`wxID_OK/wxID_CANCEL/wxID_YES/wxID_NO/wxID_HELP` (`:269-275`), but **`wxMessageBox()` returns
|
||||
`wxYES/wxNO/wxCANCEL/wxOK/wxHELP`** (`:308-312`). `wxRichMessageDialog` is native only on MSW and
|
||||
generic elsewhere (`interface/wx/richmsgdlg.h:18-23`). On MSW every `TaskDialog`-based dialog
|
||||
(`wxMessageBox`, `wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`) ignores dark mode
|
||||
(`interface/wx/app.h:1436-1440`).
|
||||
(`wxMessageBox`, `wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`) has followed dark mode
|
||||
since 3.3.3 (`interface/wx/app.h:1442-1448`).
|
||||
|
||||
**OrcaSlicer.** UI code uses the MsgDialog family (`MessageDialog`, `RichMessageDialog`,
|
||||
`WarningDialog`, `ErrorDialog`, `InfoDialog`; `references/windows-dialogs.md` §MsgDialog family) for
|
||||
@@ -848,7 +852,7 @@ Orca does not use `wxConfig`/`wxFileConfig` (so the 3.3 change of the Unix defau
|
||||
|
||||
**Contract** (`interface/wx/secretstore.h`): on Unix it needs libsecret and a running secret service, so
|
||||
always check `IsOk(&errmsg)` (`:193-210, 257`); libsecret is no longer required at run time
|
||||
(`docs/changes.txt:533`), so a missing library or service shows up only as `IsOk()` false.
|
||||
(`docs/changes.txt:726`), so a missing library or service shows up only as `IsOk()` false.
|
||||
`GetDefault()` "may show a dialog to the user under some platforms, so it can take an arbitrarily long
|
||||
time to return" (`:243-246`). One username per service (`:260-268`).
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ yields and nested event loops, progress dialogs, startup, shutdown and exception
|
||||
screen, and the access rules for `wxGetApp()` and `app_config`. Read it whenever code runs off the
|
||||
main thread, defers work, starts a timer, yields, shows progress, or runs during startup or shutdown.
|
||||
|
||||
wx cites are relative to the pinned wx 3.3.2 tree (located as in `SKILL.md` §Ground truth).
|
||||
wx cites are relative to the pinned wx 3.3.4 tree (located as in `SKILL.md` §Ground truth).
|
||||
Orca builds wx with `wxBUILD_DEBUG_LEVEL=0` and `libslic3r_gui` with `wxDEBUG_LEVEL=0`, so `wxASSERT`
|
||||
is compiled out and `wxCHECK*` returns silently: a timer started off the main thread never fires on macOS,
|
||||
`Exit()` on a loop that is not the active one is ignored, `Start(0)` on macOS fails — all without
|
||||
@@ -454,12 +454,12 @@ and aborts the whole app. Wrap the entire body; log and convert to a status the
|
||||
`wxMessageQueue::Post(T&&)` accepts move-only types (`interface/wx/msgqueue.h:90-97`).
|
||||
- `wxTHREAD_WAIT_DEFAULT` is now `wxTHREAD_WAIT_BLOCK`; `wxTHREAD_WAIT_YIELD` "is dangerous" and "is
|
||||
only implemented in wxMSW and simply ignored under the other platforms" (`interface/wx/thread.h:648-675`),
|
||||
so the 3.3 default change (`docs/changes.txt:39-41`) only affects MSW code calling
|
||||
so the 3.3 default change (`docs/changes.txt:45-47`) only affects MSW code calling
|
||||
`Wait()`/`Delete()` from the GUI thread.
|
||||
- `wxCRITICAL_SECTION(name)` declares a function-static critical section, which is initialised
|
||||
safely only if the function is first called from the main thread before other threads call it;
|
||||
otherwise make it a global (`interface/wx/thread.h:1762-1779`). Prefer `std::mutex`.
|
||||
- `wxSecretStore` documents no thread-affinity notes in 3.3.2 (`interface/wx/secretstore.h`).
|
||||
- `wxSecretStore` documents no thread-affinity notes in 3.3.4 (`interface/wx/secretstore.h`).
|
||||
|
||||
## The Jobs framework
|
||||
|
||||
@@ -829,8 +829,8 @@ nothing) (`interface/wx/utils.h:1203-1212, 1243-1248`; see `references/strings-i
|
||||
|
||||
**Platforms.** On MSW `wxProgressDialog` is native: a TaskDialog run by a
|
||||
`wxProgressDialogTaskRunner` **wxThread**, yielding `ALL & ~USER_INPUT` (TIMER and THREAD included)
|
||||
(`src/msw/progdlg.cpp` `DispatchEvents`) **[source]**; anything based on `TaskDialog()` has no dark
|
||||
mode (`interface/wx/app.h:1436-1440`). On macOS and GTK it is `wxGenericProgressDialog`, which creates
|
||||
(`src/msw/progdlg.cpp` `DispatchEvents`) **[source]**; the native `TaskDialog` follows wx dark mode
|
||||
since 3.3.3 (`interface/wx/app.h:1442-1448`). On macOS and GTK it is `wxGenericProgressDialog`, which creates
|
||||
a temporary event loop if none is active (`src/generic/progdlgg.cpp:360-366`). On MSW (native
|
||||
dialog or Orca's generic one) and macOS, `CallAfter` bodies run inside `Update()`/`Pulse()`; on GTK
|
||||
the masked yield runs no queued event, so they wait until control returns to an event loop
|
||||
@@ -839,7 +839,7 @@ the masked yield runs no queued event, so they wait until control returns to an
|
||||
**OrcaSlicer.**
|
||||
- `Slic3r::GUI::ProgressDialog` (`Widgets/ProgressDialog.hpp`) is a themed fork of
|
||||
`wxGenericProgressDialog`: same `YieldFor(UI | USER_INPUT)` semantics, temporary event loop when
|
||||
none is active, generic on every platform (so no TaskDialog dark-mode gap).
|
||||
none is active, generic on every platform (so it is themed by Orca, not the native TaskDialog).
|
||||
- `detail::run_off_thread_with_progress` (`PluginsDialog.hpp`, wrapped by
|
||||
`PluginsDialog::run_with_dialog`/`run_with_dialog_wait`): a heap wx `wxProgressDialog` (the native
|
||||
TaskDialog on MSW, the generic dialog on macOS and GTK) pulsed by a
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# WebView, OpenGL canvas, AUI docking and media
|
||||
|
||||
How wxWebView, wxGLCanvas/wxGLContext, wxAuiManager/wxAuiToolBar and the camera view behave in the
|
||||
wx 3.3.2 tree Orca builds, and the Orca wrappers built on them: `WebView`, `WebViewHostDialog` and
|
||||
wx 3.3.4 tree Orca builds, and the Orca wrappers built on them: `WebView`, `WebViewHostDialog` and
|
||||
the web dialogs/panels, `OpenGLManager`, `GLCanvas3D` and its ImGui layer, the Plater docking
|
||||
manager, `BBLTopbar`, `wxMediaCtrl3`. Read it before touching any browser view, GL canvas, docked
|
||||
pane, the top bar or the camera view, or when debugging a blank web page, a black or garbled 3D
|
||||
@@ -242,7 +242,7 @@ a single message handler and the Chromium and IE backends do not support script
|
||||
| `Add…` return | `false` if *any* handler already exists, whatever its name (`src/msw/webview_edge.cpp:1635-1645`) | always `true` (`src/osx/webview_webkit.mm:620-629`); a duplicate name makes WebKit raise an NSException that cannot be caught and kills the app ([external]: Apple behaviour, recorded in the `WebView::CreateWebView` comment) | `false` on a duplicate or with no view, **but** `g_signal_connect` runs before registration, so a duplicate add leaves a second connection (`src/gtk/webview_webkit2.cpp:1638-1657`) |
|
||||
| `Remove…` | clears the single name (`1647-1652`) | removes the native handler (`632-636`) | unregisters but **does not disconnect** the signal (`1659-1664`): Remove + Add delivers every later message **twice** |
|
||||
| `window.<name>` alias | user script `window.<name> = window.chrome.webview` + `ExecuteScript` (`1030-1046`) | `AddUserScript` + **synchronous** `RunScript` (`626-628`) | `AddUserScript` + **synchronous** `RunScript` (`1650-1654`) |
|
||||
| Delivery | queued with `AddPendingEvent` (`785-813`); [documented] "Queue Edge wxWebView events" (`docs/changes.txt:525`) | `ProcessWindowEvent` **inside** the `WKScriptMessageHandler` delegate (`1324-1361`) | `HandleWindowEvent` **inside** the GTK signal (`397-409`) |
|
||||
| Delivery | queued with `AddPendingEvent` (`785-813`); [documented] "Queue Edge wxWebView events" (`docs/changes.txt:718`) | `ProcessWindowEvent` **inside** the `WKScriptMessageHandler` delegate (`1324-1361`) | `HandleWindowEvent` **inside** the GTK signal (`397-409`) |
|
||||
| Event fields | handler name and event object set | name set, **no event object** | **empty `GetMessageHandler()`, no event object** |
|
||||
| Body | `get_WebMessageAsJson`, JSON-decoded when it is a string (`798-809`) | NSString as is; dict/array → JSON; NSNumber → `stringValue` (booleans arrive as `1`/`0`); NSNull → `"null"` | object → JSON string, otherwise `ToString` (`64-94`) |
|
||||
|
||||
@@ -710,8 +710,8 @@ the environment variable `wx_opengl_egl=0` does the same; it exists only when `w
|
||||
returns true only when EGL is in use (false when `wxHAS_EGL` is undefined); `GetGLXVersion()` returns 0
|
||||
when GLX is not in use; both exist only when `wxHAS_GLX` is defined (`interface/wx/glcanvas.h:999-1030`).
|
||||
`wxGLCanvas::CreateSurface()` was removed "as exposing it doesn't make sense when wxGLCanvas may use
|
||||
either EGL or GLX" (`docs/changes.txt:250-252`); "Allow using GLX and EGL in same program (#26023)" is
|
||||
an upstream 3.3.2 wxGTK change (`docs/changes.txt:290-292`).
|
||||
either EGL or GLX" (`docs/changes.txt:282-284`); "Allow using GLX and EGL in same program (#26023)" is
|
||||
an upstream 3.3.2 wxGTK change (`docs/changes.txt:485`).
|
||||
|
||||
**Source** [source]:
|
||||
- When both backends are built, **EGL is the default even on X11** unless `PreferGLX()` or the
|
||||
@@ -727,7 +727,7 @@ an upstream 3.3.2 wxGTK change (`docs/changes.txt:290-292`).
|
||||
(`src/unix/glegl.cpp:801-860`).
|
||||
- The EGL-based `wxGLCanvas` for Wayland dates from 3.1.5 (`docs/changes_32.txt:497`), so it predates
|
||||
Orca's upgrade; its
|
||||
high-DPI scale under EGL/Wayland was fixed in 3.3.0 (`docs/changes.txt:538`).
|
||||
high-DPI scale under EGL/Wayland was fixed in 3.3.0 (`docs/changes.txt:731`).
|
||||
|
||||
**OrcaSlicer.**
|
||||
- `deps/wxWidgets/wxWidgets.cmake` passes `-DwxUSE_GLCANVAS_EGL=ON` (also in the Flatpak manifest).
|
||||
@@ -956,13 +956,13 @@ widgets beside the canvas (a sibling, not a child over it), or in a popup.
|
||||
`src/aui/framemanager.cpp:910-920`; `OnPaneButton`); `DestroyOnClose` panes are detached and `Destroy()`ed
|
||||
(`ClosePane`, `1431-1467`). With several handlers bound, each must `Skip()`.
|
||||
- **3.3 changes.** `wxAUI_MGR_HINT_FADE` left the default flags (`interface/wx/aui/framemanager.h:43-50`;
|
||||
`docs/changes.txt:132`); `wxAUI_MGR_LIVE_RESIZE` joined them (`interface/wx/aui/framemanager.h:59-62`); `AlwaysUsesLiveResize()` "always
|
||||
`docs/changes.txt:138`); `wxAUI_MGR_LIVE_RESIZE` joined them (`interface/wx/aui/framemanager.h:59-62`); `AlwaysUsesLiveResize()` "always
|
||||
returns false" as of 3.3.0 (`interface/wx/aui/framemanager.h:345`; `src/aui/framemanager.cpp:711-714`), non-live resize being
|
||||
restored (`docs/changes.txt:490`) — the older "live resize is always used on wxOSX and GTK3/Wayland"
|
||||
restored (`docs/changes.txt:683`) — the older "live resize is always used on wxOSX and GTK3/Wayland"
|
||||
statement (`interface/wx/aui/framemanager.h:336-340`) is obsolete. Docking hints for floating frames use
|
||||
`::wxGetMousePosition()` (`src/aui/framemanager.cpp:4139-4148`, `4242-4251`), which Wayland cannot supply.
|
||||
- `wxAuiNotebook` (not used by Orca): page indices are logical; use `GetPagePosition()` for on-screen
|
||||
order (`docs/changes.txt:121-126`); the default tab art changed (`35-37`).
|
||||
order (`docs/changes.txt:128-132`); the default tab art changed (`41-43`).
|
||||
|
||||
**OrcaSlicer.** Orca's docks use `AuiMgr` (`AuiMgr.hpp`), a `wxAuiManager` whose `CreateFloatingFrame`
|
||||
returns a `wxAuiFloatingFrame` that applies `UpdateFrameDarkUI`. `init(window)` calls
|
||||
@@ -1034,8 +1034,10 @@ Plater (Prepare and Preview); `DesignPanel::m_aui` manages the Design tab's body
|
||||
```
|
||||
- **Rule:** Disable floating on Wayland (clear `wxAUI_MGR_ALLOW_FLOATING`, `Floatable(false)`, strip
|
||||
floating state from saved layouts).
|
||||
**Why:** AUI's floating and docking-hint logic needs global pointer positions and top-level window
|
||||
moves (`wxGetMousePosition`, `wxEVT_MOVE`), which Wayland does not provide.
|
||||
**Why:** AUI's docking-hint logic needs global pointer positions and top-level window moves
|
||||
(`wxGetMousePosition`, `wxEVT_MOVE`), which Wayland does not provide. 3.3.4 added system drag sessions
|
||||
so wx can move a pane's floating frame there anyway (`src/aui/framemanager.cpp` `StartDragSession`),
|
||||
but the drop/docking hints still cannot work, so Orca keeps floating disabled.
|
||||
|
||||
## wxAuiToolBar and BBLTopbar
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ port; what Orca's `DPIDialog`/`DPIFrame` add; the Orca dialog recipe; and the `M
|
||||
Read it before writing or reviewing any dialog, frame, close handler, `Destroy()`/`delete`, or code
|
||||
that keeps a pointer to a window across an event, a `CallAfter` or a modal loop.
|
||||
|
||||
wx cites are relative to the pinned wx 3.3.2 tree (located as in `SKILL.md` §Ground truth). wx is
|
||||
wx cites are relative to the pinned wx 3.3.4 tree (located as in `SKILL.md` §Ground truth). wx is
|
||||
built with `wxBUILD_DEBUG_LEVEL=0` and `libslic3r_gui` with `wxDEBUG_LEVEL=0`: every wx assert
|
||||
quoted below is compiled out, so misuse fails silently (dropped call, stuck loop, freed memory), never with an assert dialog. "GTK" below
|
||||
means wxGTK as Orca builds it on Linux: GTK3 by default (X11 or Wayland); GTK2 is only an opt-out.
|
||||
@@ -424,7 +424,7 @@ mapped (`src/gtk/toplevel.cpp:1141-1243`).
|
||||
|
||||
**Raise.** "only requests the window manager to raise this window… If the window is currently hidden,
|
||||
this function does *not* show it", top-level windows only (`interface/wx/window.h:3013-3033`); true on all ports
|
||||
since 3.3 (`docs/changes.txt:144-146`). **[source]** MSW = `::SetForegroundWindow`, subject to the
|
||||
since 3.3 (`docs/changes.txt:145-147`). **[source]** MSW = `::SetForegroundWindow`, subject to the
|
||||
foreground lock — Windows may only flash the taskbar button (`src/msw/toplevel.cpp:650-655`); GTK =
|
||||
`gtk_window_present` only if shown (`src/gtk/toplevel.cpp:1301-1310`; during a deferred X11 first show it
|
||||
already counts as shown); macOS = `makeKeyAndOrderFront` only if shown (`src/osx/nonownedwnd_osx.cpp:289-295`, `src/osx/cocoa/nonownedwnd.mm:897-899`),
|
||||
@@ -910,8 +910,9 @@ buttons are chosen — in numeric id order, so `{"Save", "OK"}` makes Save prima
|
||||
**Rule.** Never `wxMessageBox`/`wxMessageDialog`/`wxRichMessageDialog` once the GUI exists; use the themed
|
||||
replacements in `src/slic3r/GUI/MsgDialog.hpp` (`Slic3r::GUI`), rooted in `MsgDialog : DPIDialog` (logo on the
|
||||
left, content on the right, `Button` row underneath, dark-mode and DPI aware). Why: on MSW the TaskDialog-based
|
||||
native boxes (`wxMessageBox`, `wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`) ignore dark mode
|
||||
(`interface/wx/app.h:1436-1446`), and native boxes cannot match Orca's look. `wxMessageBox` remains only for
|
||||
native boxes (`wxMessageBox`, `wxMessageDialog`, `wxRichMessageDialog`, `wxProgressDialog`) now follow dark mode
|
||||
since 3.3.3, so only the date/time/calendar controls, `wxPrintDialog` on Windows 10 and MDI applications stay
|
||||
light (`interface/wx/app.h:1442-1448`); native boxes cannot match Orca's look. `wxMessageBox` remains only for
|
||||
failures before the GUI exists (e.g. `GUI_App::load_language`). Native message-box style limits:
|
||||
`references/strings-i18n-files.md`. Return-value trap when reading old code: `wxMessageBox()` returns
|
||||
`wxYES/wxNO/wxCANCEL/wxOK/wxHELP`, while `ShowModal()` returns `wxID_YES/…` (`interface/wx/msgdlg.h:269-276` vs `309-311`).
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# wx 3.1.5 → 3.3.2: changes Orca code can trip on
|
||||
# wx 3.1.5 → 3.3.4: changes Orca code can trip on
|
||||
|
||||
OrcaSlicer moved from wxWidgets **3.1.5** to **3.3.2** (8248b06337, #12941). This file digests the
|
||||
OrcaSlicer moved from wxWidgets **3.1.5** to **3.3.2** (8248b06337, #12941) and the pin is now upstream
|
||||
**3.3.4** (`deps/wxWidgets/wxWidgets.cmake`, tag `v3.3.4`). This file digests the
|
||||
changes between those versions that matter to GUI code — the 3.1.6–3.2.0 incompatible changes, the
|
||||
3.3 incompatible changes, and the notable 3.3.0/3.3.1/3.3.2 changes — each with what it means for
|
||||
Orca, plus the migration already done in Orca as rules for new code. Read it when code written
|
||||
from older wx knowledge behaves oddly, when a wx doc says "since 3.3", or when reviewing code near
|
||||
the workarounds in §8. Where this file and prior wx knowledge disagree, this file wins.
|
||||
3.3 incompatible changes, and the notable 3.3.0/3.3.1/3.3.2/3.3.3/3.3.4 changes — each with what it
|
||||
means for Orca, plus the migration already done in Orca as rules for new code. Read it when code
|
||||
written from older wx knowledge behaves oddly, when a wx doc says "since 3.3", or when reviewing code
|
||||
near the workarounds in §10. Where this file and prior wx knowledge disagree, this file wins.
|
||||
|
||||
Contents: [Rules](#rules) · [1 Reading the change logs](#1-reading-the-change-logs) ·
|
||||
[2 3.1.6 → 3.2.0](#2-changes-from-316-to-320) · [3 3.3 behaviour changes](#3-33-behaviour-changes-that-compile) ·
|
||||
[4 3.3 build changes](#4-33-changes-that-break-the-build) · [5 3.3.0](#5-330-notable-changes) ·
|
||||
[6 3.3.1](#6-331-notable-fixes) · [7 3.3.2](#7-332-notable-changes) ·
|
||||
[8 Migration done in Orca](#8-migration-already-done-in-orca)
|
||||
[8 3.3.3](#8-333-notable-changes) · [9 3.3.4](#9-334-notable-changes) ·
|
||||
[10 Migration done in Orca](#10-migration-already-done-in-orca)
|
||||
|
||||
All `docs/`, `interface/`, `include/`, `src/`, `build/` cites are relative to the pinned wx tree
|
||||
(located as in `SKILL.md` §Ground truth), except paths
|
||||
@@ -21,8 +23,8 @@ explicitly called Orca's (`deps/…`, Orca's `src/CMakeLists.txt`) and bare Orca
|
||||
|
||||
1. Read every "now asserts" in the change logs as "now silently returns or does nothing" in Orca:
|
||||
wx asserts are compiled out. Validate arguments yourself. → [§1](#1-reading-the-change-logs)
|
||||
2. Target 3.3.2 only. Do not add `wxCHECK_VERSION` / `wxVERSION_NUMBER` /
|
||||
`wxVERSION_EQUAL_OR_GREATER_THAN` branches for older wx. → [§8](#8-migration-already-done-in-orca)
|
||||
2. Target 3.3.4 only. Do not add `wxCHECK_VERSION` / `wxVERSION_NUMBER` /
|
||||
`wxVERSION_EQUAL_OR_GREATER_THAN` branches for older wx. → [§10](#10-migration-already-done-in-orca)
|
||||
3. Mark every override of a wx virtual `override`. 3.2/3.3 changed parameter types (`wxBitmapBundle`,
|
||||
`wxReadOnlyDC`, `wxWindowBase*`, `wxVersionContext`); a stale signature must fail to compile, not
|
||||
become a silent overload. → [§4](#4-33-changes-that-break-the-build)
|
||||
@@ -39,33 +41,36 @@ explicitly called Orca's (`deps/…`, Orca's `src/CMakeLists.txt`) and bare Orca
|
||||
`WX_GL_SAMPLES`); `wxGLAttributes::Defaults()` no longer includes it. → [§3](#3-33-behaviour-changes-that-compile)
|
||||
9. Size a `wxImageList` in physical pixels (the bitmaps' `GetSize()`), or use the `wxBitmapBundle`
|
||||
image APIs. → [§3](#3-33-behaviour-changes-that-compile)
|
||||
10. Return translated strings as `wxString` by value. → [§3](#3-33-behaviour-changes-that-compile)
|
||||
10. `wxGetTranslation()` returns `const wxString&` (3.3.2 made it by-value; 3.3.3 reverted that); a
|
||||
wrapper that converts a translation returns by value. → [§3](#3-33-behaviour-changes-that-compile)
|
||||
11. Escape `&` in user text used as a control label or book page title. → [§3](#3-33-behaviour-changes-that-compile)
|
||||
12. `wxDynamicCast` only on a pointer whose static type derives from `wxObject`; use `dynamic_cast`
|
||||
for mixin interfaces (`wxComboPopup`, `wxItemContainer`, `wxTextEntry`). → [§4](#4-33-changes-that-break-the-build)
|
||||
13. Build a `wxArrayString` with `Add()` or an initializer list, walk wx lists with
|
||||
`compatibility_iterator` or range-for, and make a `wxString` the first operand of a mixed
|
||||
`+` chain. → [§4](#4-33-changes-that-break-the-build)
|
||||
14. MSW windows are not double-buffered by default in 3.3.2; a custom-painted control buffers itself.
|
||||
14. MSW windows are not double-buffered by default in 3.3.4; a custom-painted control buffers itself.
|
||||
→ [§5](#5-330-notable-changes)
|
||||
15. `wxEVT_DPI_CHANGED` now fires on GTK3 too; such handlers must be correct on GTK, and every handler
|
||||
you bind calls `Skip()` (`DPIAware`'s own is the one exception). → [§5](#5-330-notable-changes)
|
||||
16. wx MSW dark mode cannot be switched at runtime; do not replace Orca's NppDarkMode with it without
|
||||
keeping live theme switching. → [§5](#5-330-notable-changes)
|
||||
16. wx MSW dark mode became runtime-switchable in 3.3.3/3.3.4 (`SetAppearance`/`MSWEnableDarkMode`
|
||||
restyle existing windows); Orca still keeps NppDarkMode for its own chrome.
|
||||
→ [§5](#5-330-notable-changes), [§9](#9-334-notable-changes)
|
||||
17. After `wxStaticText::SetLabel`, re-wrap with `Wrap(-1); Wrap(w);` (or use `Label`); `wxST_WRAP`
|
||||
is opt-in and works only inside a sizer. → [§7](#7-332-notable-changes)
|
||||
18. On Linux/X11 call `wxGLCanvas::PreferGLX()` before any GL use; on Unix set a swap interval explicitly
|
||||
if frame pacing matters (wx forces 0). → [§7](#7-332-notable-changes)
|
||||
19. Compare `wxGrid::GetSelectedBlocks()` `begin()` with `end()` before dereferencing.
|
||||
→ [§8](#8-migration-already-done-in-orca)
|
||||
→ [§10](#10-migration-already-done-in-orca)
|
||||
20. Keep the post-upgrade workarounds (MainFrame `WS_CAPTION` masking, macOS deep-link handler,
|
||||
`MSWEnableDarkMode` ordering, `SidePopup` anchoring, MSW `GLCanvas3D::on_paint` render) when
|
||||
touching that code. → [§8](#8-migration-already-done-in-orca)
|
||||
touching that code. → [§10](#10-migration-already-done-in-orca)
|
||||
|
||||
## 1 Reading the change logs
|
||||
|
||||
**Sources.** `docs/changes.txt` lists changes since 3.2: incompatible behaviour changes :11-146,
|
||||
build-breaking changes :149-252, 3.3.2 :255-330, 3.3.1 :333-377, 3.3.0 :380-622.
|
||||
**Sources.** `docs/changes.txt` lists changes since 3.2: incompatible behaviour changes :11-178,
|
||||
build-breaking changes :181-292, 3.3.4 :295-385, 3.3.3 :388-445, 3.3.2 :448-523, 3.3.1 :526-570,
|
||||
3.3.0 :573-815.
|
||||
`docs/changes_32.txt` covers 3.x → 3.2.0: the cumulative "INCOMPATIBLE CHANGES SINCE 3.0.x" list
|
||||
:9-233, 3.2.0 :235-276, 3.1.7 :279-340, 3.1.6 :343-444. wxQt, wxiOS, wxUniv, wxMotif and wxGTK1
|
||||
items are left out here.
|
||||
@@ -73,11 +78,14 @@ items are left out here.
|
||||
**Coverage gaps.**
|
||||
- The "since 3.0.x" list in `changes_32.txt` is cumulative over all of 3.1.x. Most of it was already
|
||||
in force in 3.1.5; §2.1 lists only what was added after 3.1.5, §2.3 the older items worth knowing.
|
||||
- `changes_32.txt` in this tree stops at 3.2.0. The 3.2.1–3.2.10 maintenance fixes are not listed
|
||||
- `changes_32.txt` in this tree stops at 3.2.0. The 3.2.1–3.2.12 maintenance fixes are not listed
|
||||
anywhere in the tree.
|
||||
- 3.3.0's list is relative to 3.2.8 (`changes.txt:383`). 3.3.2's list is relative to 3.2.10, and the
|
||||
- 3.3.0's list is relative to 3.2.8 (`changes.txt:576`). 3.3.2's list is relative to 3.2.10, and the
|
||||
full set of changes since 3.3.1 *also includes* the 3.2.9 and 3.2.10 fixes, which are **not**
|
||||
listed in this file (`changes.txt:258-259`).
|
||||
listed in this file (`changes.txt:451-452`). 3.3.3's list is relative to 3.2.11, and its changes
|
||||
since 3.3.2 *also include* the 3.2.10–3.2.11 fixes (`changes.txt:391-392`); 3.3.4's list is
|
||||
relative to 3.2.11 too, and its changes since 3.3.3 *also include* the 3.2.11–3.2.12 fixes
|
||||
(`changes.txt:298-299`).
|
||||
|
||||
**"Asserts" mean silence in Orca.** wx is built with `-DwxBUILD_DEBUG_LEVEL=0`
|
||||
(`deps/wxWidgets/wxWidgets.cmake` → `build/cmake/init.cmake:245-246`), and `libslic3r_gui` gets
|
||||
@@ -117,7 +125,7 @@ the 3.1.7-specific section.
|
||||
| `wxSpinCtrl::SetValue(wxString)` sends no events on MSW (as documented) | :129-130 | do not rely on setter events (`controls-dataview.md`) |
|
||||
| `wxButton::GetBitmap{Current,Disabled,Focus,Pressed}()` return a valid bitmap on MSW only if set | :132-134 | check `IsOk()` |
|
||||
| `wxFileName::GetVolume()` returns `\\share` for UNC paths and `\\?\Volume{GUID}` for GUID paths | :136-140 | path code comparing volumes |
|
||||
| `wxBitmapComboBoxBase::SetItemBitmap()` takes `wxBitmapBundle` | :152-153 | the bundle change also retyped `OnAddBitmap` (5f365b5c6b, §8) |
|
||||
| `wxBitmapComboBoxBase::SetItemBitmap()` takes `wxBitmapBundle` | :152-153 | the bundle change also retyped `OnAddBitmap` (5f365b5c6b, §10) |
|
||||
| MSW also links `oleacc` (3.1.5 already needed `shlwapi`, `uxtheme`, `version`) | :158-163 | automatic with MSVC |
|
||||
| Xcode projects drop i386, add arm64 | :205-207 | none (CMake build) |
|
||||
| `wxImage` ctor from XPM data is `explicit` | :225-226 | write `wxImage(xpm)` |
|
||||
@@ -136,7 +144,7 @@ the 3.1.7-specific section.
|
||||
| MSW: TLW resizing on DPI change improved and overridable — a handler that sizes the TLW itself does not `Skip()` (3.2.0) | `changes_32.txt:269`; `interface/wx/event.h` (`wxDPIChangedEvent`) | Orca's `DPIAware` handler does not `Skip()` (`dpi-bitmaps-fonts.md`) |
|
||||
| `wxUILocale` (3.1.6); `wxLocale::IsAvailable` is now implemented through it | `changes_32.txt:348`; `src/common/intl.cpp:740-781` | see `wxUILocale::IsSupported` in §3 |
|
||||
| `wxWebView::RunScriptAsync()` (3.1.6) | `changes_32.txt:382` | `webview-gl-aui-media.md` |
|
||||
| wxOSX: "Allow user input in `wxPopupTransientWindow`" (3.1.7) — the popup's child holds mouse capture while the cursor is outside it and releases it inside, toggled from `OnIdle` [source] | `changes_32.txt:334`; `src/common/popupcmn.cpp:438-471` | how wxOSX transient popups track the mouse; the macOS gap-dismissal worked around in `SidePopup::Popup` is not traced to a specific wx change (§8; `popups-menus.md`) |
|
||||
| wxOSX: "Allow user input in `wxPopupTransientWindow`" (3.1.7) — the popup's child holds mouse capture while the cursor is outside it and releases it inside, toggled from `OnIdle` [source] | `changes_32.txt:334`; `src/common/popupcmn.cpp:438-471` | how wxOSX transient popups track the mouse; the macOS gap-dismissal worked around in `SidePopup::Popup` is not traced to a specific wx change (§10; `popups-menus.md`) |
|
||||
| wxGTK: Wayland fixes (3.1.6), no GDK errors from `PopupMenu()` on Wayland (3.1.7), `wxCURSOR_SIZING` on Wayland (3.2.0) | `changes_32.txt:397, 317, 261` | `platforms.md` |
|
||||
| MSW: all native modal dialogs are app-modal (3.1.6) | `changes_32.txt:409` | `windows-dialogs.md` |
|
||||
| Also new: `wxKeyEvent::IsAutoRepeat()`, `wxSpinCtrl::GetTextValue()/SetIncrement()`, `wxTopLevelWindow::SetContentProtection()`, `wxEVT_SPLITTER_SASH_POS_RESIZE`, OSX full-screen view options, OSX `wxEVT_CHAR` from `wxDataViewCtrl` | `changes_32.txt:364-436` | available API |
|
||||
@@ -167,7 +175,7 @@ These were already in force in 3.1.5, so the upgrade did not change them, but co
|
||||
|
||||
## 3 3.3 behaviour changes that compile
|
||||
|
||||
`changes.txt` "Changes in behaviour not resulting in compilation errors" (:11-146). Each row: the
|
||||
`changes.txt` "Changes in behaviour not resulting in compilation errors" (:11-178). Each row: the
|
||||
change, its line, and what it means for Orca.
|
||||
|
||||
| Change | Line | Orca relevance |
|
||||
@@ -177,31 +185,30 @@ change, its line, and what it means for Orca.
|
||||
| `wxGLCanvas` no longer multisamples by default | :21-23 | pitfall below |
|
||||
| `wxFileConfig` on Unix defaults to XDG `~/.config/appname.conf` (old file still used; `wxCONFIG_USE_XDG`/`wxCONFIG_USE_HOME`, `MigrateLocalFile()`) | :25-29 | none: Orca uses `AppConfig`, no `wxConfig` (`strings-i18n-files.md`) |
|
||||
| `wxColourDatabase` uses CSS values; `UseScheme()` restores the old ones (`interface/wx/gdicmn.h:845, 973-996`) | :31-33 | none: stock colours (`*wxGREEN`, …) are fixed RGB (`src/common/gdicmn.cpp:789-830`) and Orca builds colours from hex/RGB. Do not build colours from names |
|
||||
| `wxAuiNotebook` default art is the new flat art; `wxAuiNativeTabArt` (or `"native"` in XRC) keeps the old look | :35-37 | none: no `wxAuiNotebook` in Orca |
|
||||
| `wxTHREAD_WAIT_DEFAULT` is `wxTHREAD_WAIT_BLOCK`: `wxThread::Delete()/Wait()` no longer pump events | :39-41 | Orca uses std/boost threads (`wxThread` only for `IsMain()`); a new `wxThread` whose exit needs the main loop would deadlock |
|
||||
| `wxDocument::OnCloseDocument()` runs once, after the views are destroyed (it used to run twice when the document was closed from the menu); an override must not rely on any view existing | :43-46 | none: no doc/view |
|
||||
| `wxGrid::FreezeTo()` asserts on out-of-range counts, and freezes even when the grid is too small | :48-51 | silent `false` in Orca; it also refuses reordered or drag-movable rows/columns [source] (`src/generic/grid.cpp:5742-5750`). Clamp arguments (`controls-dataview.md`) |
|
||||
| Invalid `wxImageList` calls assert | :53-56 | silent in Orca; `wxCHECK` returns (generic `Add` → -1). Create the list with a valid size before use |
|
||||
| `wxTRANSPARENT_WINDOW` does nothing (`#define wxTRANSPARENT_WINDOW 0`, `include/wx/defs.h:1449`); MSW code that needs it can set `WS_EX_TRANSPARENT` | :58-60 | pitfall below; 026b105dcb |
|
||||
| MSW `wxTextDataObject::SetData()` size includes the 2-byte NUL (consistent with `GetDataSize()`); an old-style size chops the last character | :62-66 | none: Orca uses the `wxTextDataObject(text)` ctor; use `SetText()`, never `SetData()` |
|
||||
| `wxListCtrl::EditLabel()` asserts without `wxLC_EDIT_LABELS` | :68-69 | silent no-op in Orca; add the style where editing is intended |
|
||||
| MSW `wxSystemAppearance::IsDark()` reports the app's own mode; `AreAppsDark()`/`IsSystemDark()` report the OS | :71-73 | pitfall below |
|
||||
| Unix `wxUILocale::IsSupported()` no longer falls back to another region of the same language; pass just `"fr"` to accept any `fr_XX` | :75-79 | `wxLocale::IsAvailable` builds the region-qualified tag (`GetCanonicalWithRegion()`) and calls `IsSupported()` [source] (`src/common/intl.cpp:740-781`); `GUI_App::load_language` relies on it, so on Linux a language whose canonical locale (e.g. `fr_FR`) is not installed reports unavailable. Keep the fallbacks in `load_language` |
|
||||
| Deprecated `wxPGCellRenderer::DrawCaptionSelectionRect()` overload not called; override the overload taking `wxWindow*`, or enable 3.0 compatibility | :81-83 | none: no propgrid in Orca's own code |
|
||||
| `wxImageList` size is in physical pixels | :85-88 | pitfall below |
|
||||
| Mac `wxWebRequest` no longer uses persistent storage. The entry names `wxWebRequest::EnablePersistentStorage()`; the real API is `wxWebSession::EnablePersistentStorage(bool)` (`interface/wx/webrequest.h:1612-1629`; also `wxWebSessionSync`, :1835), macOS-only, before the first request | :90-92 | none: Orca uses `wxWebRequest` only for image downloads (`wxWebSession::GetDefault().CreateRequest` in `StatusPanel`, `SliceInfoPanel`, `ReleaseNote`, `DeviceErrorDialog`); network and login agents use libcurl (`Slic3r::Http`) |
|
||||
| MSW `wxBitmap::Create(size, dc)` no longer multiplies by the DC's content scale; the size is physical | :94-96 | remove compensating scaling; use `CreateWithLogicalSize` for logical sizes |
|
||||
| `wxIMAGE_QUALITY_NEAREST` has a new value and is no longer `wxIMAGE_QUALITY_NORMAL`; `NORMAL` (the `Scale`/`Rescale` default) is bilinear + box average (`interface/wx/image.h:31-67`) | :98-99 | never store or compare the enum numerically; default-quality thumbnails and icons look smoother than under 3.1.5; pass `wxIMAGE_QUALITY_NEAREST` for pixel-exact scaling |
|
||||
| `wxTextCtrl::{Save,Load}File()` treat `.rtf` as RTF | :101-104 | pass `wxTEXT_TYPE_PLAIN` to keep plain text |
|
||||
| `wxClientDC`/`wxPaintDC` offset their origin by a `wxFrame` toolbar on every port | :106-109 | none: Orca frames have no native toolbar (`BBLTopbar` is a child `wxAuiToolBar`) |
|
||||
| `wxTextCtrl::SetLabel()` does nothing and asserts on every port (MSW used to act as `SetValue`) | :111-113 | pitfall below |
|
||||
| `wxAuiGenericTabArt` subclasses (also via `wxAuiMSWTabArt`) override `DrawPageTab()`/`GetPageTabSize()` instead of `DrawTab()`/`GetTabSize()`; direct `wxAuiTabArt` subclasses still work | :115-120 | none: no Orca tab art |
|
||||
| `wxAuiNotebook` page index is logical (reorder-independent); `GetPagePosition()` gives the screen position | :122-126 | none; index math under `wxAUI_NB_TAB_MOVE` is what breaks |
|
||||
| `wxListbook`/`wxChoicebook` interpret mnemonics in page titles "just as the other wx*book classes already did" | :128-130 | Orca uses neither (`BedShapeDialog` uses `wxSimplebook` + a combo); every book interprets `&` (`interface/wx/bookctrl.h:141-147`) → rule 11 |
|
||||
| `wxAUI_MGR_HINT_FADE` is not in the default `wxAuiManager` style | :132-133 | Orca's `AuiMgr` keeps the default flags (minus `wxAUI_MGR_ALLOW_FLOATING` on Wayland, `AuiMgr::init`), so the docking hint no longer fades; add the flag if wanted |
|
||||
| `wxPrintDialogData::SetAllPages(false)`/`SetSelection(false)` changed meaning | :135-137 | none |
|
||||
| `wxGetTranslation()` returns `wxString` by value | :139-142 | pitfall below |
|
||||
| `wxWindow::Raise()` no longer shows a hidden window on any port | :144-146 | pitfall below; ba867cc534 |
|
||||
| `wxAuiNotebook` default art is the new flat art; `wxAuiNativeTabArt` (or `"native"` in XRC) keeps the old look | :41-43 | none: no `wxAuiNotebook` in Orca |
|
||||
| `wxTHREAD_WAIT_DEFAULT` is `wxTHREAD_WAIT_BLOCK`: `wxThread::Delete()/Wait()` no longer pump events | :45-47 | Orca uses std/boost threads (`wxThread` only for `IsMain()`); a new `wxThread` whose exit needs the main loop would deadlock |
|
||||
| `wxDocument::OnCloseDocument()` runs once, after the views are destroyed (it used to run twice when the document was closed from the menu); an override must not rely on any view existing | :49-52 | none: no doc/view |
|
||||
| `wxGrid::FreezeTo()` asserts on out-of-range counts, and freezes even when the grid is too small | :54-57 | silent `false` in Orca; it also refuses reordered or drag-movable rows/columns [source] (`src/generic/grid.cpp:5742-5750`). Clamp arguments (`controls-dataview.md`) |
|
||||
| Invalid `wxImageList` calls assert | :59-62 | silent in Orca; `wxCHECK` returns (generic `Add` → -1). Create the list with a valid size before use |
|
||||
| `wxTRANSPARENT_WINDOW` does nothing (`#define wxTRANSPARENT_WINDOW 0`, `include/wx/defs.h:1449`); MSW code that needs it can set `WS_EX_TRANSPARENT` | :64-66 | pitfall below; 026b105dcb |
|
||||
| MSW `wxTextDataObject::SetData()` size includes the 2-byte NUL (consistent with `GetDataSize()`); an old-style size chops the last character | :68-72 | none: Orca uses the `wxTextDataObject(text)` ctor; use `SetText()`, never `SetData()` |
|
||||
| `wxListCtrl::EditLabel()` asserts without `wxLC_EDIT_LABELS` | :74-75 | silent no-op in Orca; add the style where editing is intended |
|
||||
| MSW `wxSystemAppearance::IsDark()` reports the app's own mode; `AreAppsDark()`/`IsSystemDark()` report the OS | :77-79 | pitfall below |
|
||||
| Unix `wxUILocale::IsSupported()` no longer falls back to another region of the same language; pass just `"fr"` to accept any `fr_XX` | :81-85 | `wxLocale::IsAvailable` builds the region-qualified tag (`GetCanonicalWithRegion()`) and calls `IsSupported()` [source] (`src/common/intl.cpp:740-781`); `GUI_App::load_language` relies on it, so on Linux a language whose canonical locale (e.g. `fr_FR`) is not installed reports unavailable. Keep the fallbacks in `load_language` |
|
||||
| Deprecated `wxPGCellRenderer::DrawCaptionSelectionRect()` overload not called; override the overload taking `wxWindow*`, or enable 3.0 compatibility | :87-89 | none: no propgrid in Orca's own code |
|
||||
| `wxImageList` size is in physical pixels | :91-94 | pitfall below |
|
||||
| Mac `wxWebRequest` no longer uses persistent storage. The entry names `wxWebRequest::EnablePersistentStorage()`; the real API is `wxWebSession::EnablePersistentStorage(bool)` (`interface/wx/webrequest.h:1612-1629`; also `wxWebSessionSync`, :1835), macOS-only, before the first request | :96-98 | none: Orca uses `wxWebRequest` only for image downloads (`wxWebSession::GetDefault().CreateRequest` in `StatusPanel`, `SliceInfoPanel`, `ReleaseNote`, `DeviceErrorDialog`); network and login agents use libcurl (`Slic3r::Http`) |
|
||||
| MSW `wxBitmap::Create(size, dc)` no longer multiplies by the DC's content scale; the size is physical | :100-102 | remove compensating scaling; use `CreateWithLogicalSize` for logical sizes |
|
||||
| `wxIMAGE_QUALITY_NEAREST` has a new value and is no longer `wxIMAGE_QUALITY_NORMAL`; `NORMAL` (the `Scale`/`Rescale` default) is bilinear + box average (`interface/wx/image.h:31-67`) | :104-105 | never store or compare the enum numerically; default-quality thumbnails and icons look smoother than under 3.1.5; pass `wxIMAGE_QUALITY_NEAREST` for pixel-exact scaling |
|
||||
| `wxTextCtrl::{Save,Load}File()` treat `.rtf` as RTF | :107-110 | pass `wxTEXT_TYPE_PLAIN` to keep plain text |
|
||||
| `wxClientDC`/`wxPaintDC` offset their origin by a `wxFrame` toolbar on every port | :112-115 | none: Orca frames have no native toolbar (`BBLTopbar` is a child `wxAuiToolBar`) |
|
||||
| `wxTextCtrl::SetLabel()` does nothing and asserts on every port (MSW used to act as `SetValue`) | :117-119 | pitfall below |
|
||||
| `wxAuiGenericTabArt` subclasses (also via `wxAuiMSWTabArt`) override `DrawPageTab()`/`GetPageTabSize()` instead of `DrawTab()`/`GetTabSize()`; direct `wxAuiTabArt` subclasses still work | :121-126 | none: no Orca tab art |
|
||||
| `wxAuiNotebook` page index is logical (reorder-independent); `GetPagePosition()` gives the screen position | :128-132 | none; index math under `wxAUI_NB_TAB_MOVE` is what breaks |
|
||||
| `wxListbook`/`wxChoicebook` interpret mnemonics in page titles "just as the other wx*book classes already did" | :134-136 | Orca uses neither (`BedShapeDialog` uses `wxSimplebook` + a combo); every book interprets `&` (`interface/wx/bookctrl.h:141-147`) → rule 11 |
|
||||
| `wxAUI_MGR_HINT_FADE` is not in the default `wxAuiManager` style | :138-139 | Orca's `AuiMgr` keeps the default flags (minus `wxAUI_MGR_ALLOW_FLOATING` on Wayland, `AuiMgr::init`), so the docking hint no longer fades; add the flag if wanted |
|
||||
| `wxPrintDialogData::SetAllPages(false)`/`SetSelection(false)` changed meaning | :141-143 | none |
|
||||
| `wxWindow::Raise()` no longer shows a hidden window on any port | :145-147 | pitfall below; ba867cc534 |
|
||||
|
||||
**Pitfalls**
|
||||
|
||||
@@ -277,7 +284,7 @@ change, its line, and what it means for Orca.
|
||||
// Wrong: m_input_ip->GetTextCtrl()->SetLabelText(m_obj->get_dev_ip());
|
||||
// Right: m_input_ip->GetTextCtrl()->ChangeValue(m_obj->get_dev_ip()); // no wxEVT_TEXT
|
||||
```
|
||||
Cite: `docs/changes.txt:111-113`; `controls-dataview.md`.
|
||||
Cite: `docs/changes.txt:117-119`; `controls-dataview.md`.
|
||||
|
||||
- **Rule:** Size a `wxImageList` from the bitmaps' physical size, or use
|
||||
`SetImages(std::vector<wxBitmapBundle>)`.
|
||||
@@ -293,18 +300,23 @@ change, its line, and what it means for Orca.
|
||||
// Right: wxBitmap bmp = create_scaled_bitmap("icon", this, 16);
|
||||
// m_images = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), false);
|
||||
```
|
||||
Cite: `docs/changes.txt:85-88`; `Tab` builds its list from `bmp().GetWidth()/GetHeight()`;
|
||||
Cite: `docs/changes.txt:91-94`; `Tab` builds its list from `bmp().GetWidth()/GetHeight()`;
|
||||
`dpi-bitmaps-fonts.md`.
|
||||
|
||||
- **Rule:** A function that returns a translation returns `wxString` by value.
|
||||
**Why:** `wxGetTranslation()` returns by value now (`include/wx/translation.h:278-321`); returning
|
||||
it as `const wxString&` dangles. Orca's `I18N::translate` overloads and `_L` already return by
|
||||
value.
|
||||
- **Rule:** A wrapper that converts a translation returns by value; `wxGetTranslation()` itself
|
||||
returns `const wxString&`.
|
||||
**Why:** 3.3.2 changed `wxGetTranslation()` to return `wxString` by value, and **3.3.3 reverted it**
|
||||
(`interface/wx/translation.h:615`, `include/wx/translation.h:277-309`), so the return type is the
|
||||
3.2.x `const wxString&` again. That reference points at the catalog's own string or at
|
||||
`wxTranslations::GetUntranslatedString()`, both of which outlive the call, so forwarding it as a
|
||||
reference is safe. What still dangles is a temporary you construct: `wxString::FromUTF8`,
|
||||
`ToUTF8()`, `format_wxstr`. Orca's `I18N::translate` overloads return `wxString` by value and
|
||||
`translate_utf8`/`_u8L` return `std::string`.
|
||||
```cpp
|
||||
// Wrong: const wxString& title() { return _L("Printer"); }
|
||||
// Right: wxString title() { return _L("Printer"); }
|
||||
// Wrong: const wxString& path() { return wxString::FromUTF8(raw); } // temporary
|
||||
// Right: wxString path() { return wxString::FromUTF8(raw); }
|
||||
```
|
||||
Cite: `docs/changes.txt:139-142`; `I18N.hpp`.
|
||||
Cite: §8 (the 3.3.3 revert); `I18N.hpp`.
|
||||
|
||||
- **Rule:** Escape `&` in user data (preset, filament, printer, file names) shown as a control label or
|
||||
book page title.
|
||||
@@ -314,37 +326,37 @@ change, its line, and what it means for Orca.
|
||||
// Wrong: book->AddPage(page, preset_name);
|
||||
// Right: book->AddPage(page, wxControl::EscapeMnemonics(preset_name)); // or label->SetLabelText(name)
|
||||
```
|
||||
Cite: `docs/changes.txt:128-130`; `interface/wx/bookctrl.h:141-147`; `controls-dataview.md`.
|
||||
Cite: `docs/changes.txt:134-136`; `interface/wx/bookctrl.h:141-147`; `controls-dataview.md`.
|
||||
|
||||
## 4 3.3 changes that break the build
|
||||
|
||||
`changes.txt` "Changes in behaviour which may result in build errors" (:149-252).
|
||||
`changes.txt` "Changes in behaviour which may result in build errors" (:181-292).
|
||||
|
||||
| Change | Line | Orca relevance |
|
||||
|---|---|---|
|
||||
| 3.0-deprecated symbols disabled by default (`WXWIN_COMPATIBILITY_3_0=1` at wx build time re-enables them), 2.8-deprecated removed | :152-154 | Orca builds `WXWIN_COMPATIBILITY_3_0 0`, `_3_2 1`: port off 3.0-deprecated API |
|
||||
| `wxUSE_UNICODE=0` unsupported | :156 | none |
|
||||
| `wxUSE_STD_CONTAINERS=1` by default ("Container Classes" overview); building wx with 0 keeps the old containers | :158-161 | Orca builds with 1 → pitfall below |
|
||||
| `wxUSE_STL` gone; implicit `wxString` → `std::[w]string` only with `wxUSE_STD_STRING_CONV_IN_WXSTRING=1` at wx build time | :163-166 | Orca builds 0: convert explicitly (`into_u8`, `ToStdString`, `ToUTF8()`) |
|
||||
| MSW links `gdiplus.lib`, `msimg32.lib` | :168-172 | automatic with MSVC/wx-config; only static non-MSVC builds add them |
|
||||
| wxMotif, wxGTK1 removed | :174-175 | none |
|
||||
| Private containers (e.g. `wxSimpleDataObjectList`) removed; object arrays (`wxImageArray`) compare values in `Index()` | :177-183 | use `std::vector`/`std::list` |
|
||||
| Operators on wx types are hidden (not global) | :185-189 | pitfall below |
|
||||
| `wxString` from `std::string_view` makes `wxstr = {"Hello", 2}` ambiguous | :191-194 | write `wxString{"Hello", 2}` |
|
||||
| Generic `wxSearchCtrl` lost multi-line-only methods | :196-197 | none |
|
||||
| Wide-filename `wxOnAssert()` overload removed | :199-200 | none |
|
||||
| 64-bit DLLs carry an `x64` suffix in all build systems | :202-204 | packaging scripts matching DLL names; Orca links wx statically (Flatpak builds it shared in its own manifest) |
|
||||
| CMake config installs to `lib/cmake/wxWidgets-3.3`; plain `find_package(wxWidgets)` is unaffected, hard-coded paths break | :206-211 | Orca: `find_package(wxWidgets 3.3 CONFIG …)` on Windows/macOS, `wx-config --toolkit=gtk${SLIC3R_GTK}` on Linux (Orca's `src/CMakeLists.txt`) |
|
||||
| Memory-tracing options removed | :213-216 | use ASan |
|
||||
| `wxTEST_DIALOG()` needs a trailing `;` | :218-219 | none |
|
||||
| `wxWindow::GetDefaultBorderForControl()` not virtual | :221-223 | do not override; use `wxBORDER_THEME` |
|
||||
| GTK `wxDirButton::Create()` lost `wildcard` | :225-226 | none |
|
||||
| Several virtuals take `wxReadOnlyDC` | :228-231 | pitfall below |
|
||||
| `wxSizer::Detach()` takes `wxWindowBase*` | :233-236 | only custom sizer subclasses |
|
||||
| `wx/cursor.h` no longer includes `wx/utils.h` | :238-240 | include `<wx/utils.h>` explicitly (8248b06337 added it to `GLCanvas3D.cpp`) |
|
||||
| `wxStyledTextCtrl::AddSelection()` returns void | :242-244 | none: `wxUSE_STC=OFF` |
|
||||
| `wxColour` from `bool` no longer compiles | :246-248 | use the RGB or string ctor explicitly |
|
||||
| `wxGLCanvas::CreateSurface()` removed from EGL builds | :250-252 | none: wx chooses EGL or GLX itself (§7) |
|
||||
| 3.0-deprecated symbols disabled by default (`WXWIN_COMPATIBILITY_3_0=1` at wx build time re-enables them), 2.8-deprecated removed | :184-186 | Orca builds `WXWIN_COMPATIBILITY_3_0 0`, `_3_2 1`: port off 3.0-deprecated API |
|
||||
| `wxUSE_UNICODE=0` unsupported | :188 | none |
|
||||
| `wxUSE_STD_CONTAINERS=1` by default ("Container Classes" overview); building wx with 0 keeps the old containers | :190-193 | Orca builds with 1 → pitfall below |
|
||||
| `wxUSE_STL` gone; implicit `wxString` → `std::[w]string` only with `wxUSE_STD_STRING_CONV_IN_WXSTRING=1` at wx build time | :195-198 | Orca builds 0: convert explicitly (`into_u8`, `ToStdString`, `ToUTF8()`) |
|
||||
| MSW links `gdiplus.lib`, `msimg32.lib` | :200-204 | automatic with MSVC/wx-config; only static non-MSVC builds add them |
|
||||
| wxMotif, wxGTK1 removed | :206-207 | none |
|
||||
| Private containers (e.g. `wxSimpleDataObjectList`) removed; object arrays (`wxImageArray`) compare values in `Index()` | :209-215 | use `std::vector`/`std::list` |
|
||||
| Operators on wx types are hidden (not global) | :217-221 | pitfall below |
|
||||
| `wxString` from `std::string_view` makes `wxstr = {"Hello", 2}` ambiguous | :223-226 | write `wxString{"Hello", 2}` |
|
||||
| Generic `wxSearchCtrl` lost multi-line-only methods | :228-229 | none |
|
||||
| Wide-filename `wxOnAssert()` overload removed | :231-232 | none |
|
||||
| 64-bit DLLs carry an `x64` suffix in all build systems | :234-236 | packaging scripts matching DLL names; Orca links wx statically (Flatpak builds it shared in its own manifest) |
|
||||
| CMake config installs to `lib/cmake/wxWidgets-3.3`; plain `find_package(wxWidgets)` is unaffected, hard-coded paths break | :238-243 | Orca: `find_package(wxWidgets 3.3 CONFIG …)` on Windows/macOS, `wx-config --toolkit=gtk${SLIC3R_GTK}` on Linux (Orca's `src/CMakeLists.txt`) |
|
||||
| Memory-tracing options removed | :245-248 | use ASan |
|
||||
| `wxTEST_DIALOG()` needs a trailing `;` | :250-251 | none |
|
||||
| `wxWindow::GetDefaultBorderForControl()` not virtual | :253-255 | do not override; use `wxBORDER_THEME` |
|
||||
| GTK `wxDirButton::Create()` lost `wildcard` | :257-258 | none |
|
||||
| Several virtuals take `wxReadOnlyDC` | :260-263 | pitfall below |
|
||||
| `wxSizer::Detach()` takes `wxWindowBase*` | :265-268 | only custom sizer subclasses |
|
||||
| `wx/cursor.h` no longer includes `wx/utils.h` | :270-272 | include `<wx/utils.h>` explicitly (8248b06337 added it to `GLCanvas3D.cpp`) |
|
||||
| `wxStyledTextCtrl::AddSelection()` returns void | :274-276 | none: `wxUSE_STC=OFF` |
|
||||
| `wxColour` from `bool` no longer compiles | :278-280 | use the RGB or string ctor explicitly |
|
||||
| `wxGLCanvas::CreateSurface()` removed from EGL builds | :282-284 | none: wx chooses EGL or GLX itself (§7) |
|
||||
|
||||
**Pitfalls**
|
||||
|
||||
@@ -366,7 +378,7 @@ change, its line, and what it means for Orca.
|
||||
// Wrong: wxSize GetToolSize(wxDC& dc, wxWindow* w, const wxAuiToolBarItem& it); // never called
|
||||
// Right: wxSize GetToolSize(wxReadOnlyDC& dc, wxWindow* w, const wxAuiToolBarItem& it) override;
|
||||
```
|
||||
Cite: `docs/changes.txt:228-231`; `painting-custom-widgets.md`.
|
||||
Cite: `docs/changes.txt:260-263`; `painting-custom-widgets.md`.
|
||||
|
||||
- **Rule:** With `wxUSE_STD_CONTAINERS=1`, build a `wxArrayString` with `Add()` or an initializer
|
||||
list, and walk `WX_DECLARE_LIST` lists with `compatibility_iterator` or range-for.
|
||||
@@ -386,7 +398,7 @@ change, its line, and what it means for Orca.
|
||||
`wchar_t`, `std::string` or `std::wstring`.
|
||||
**Why:** wx operators are hidden friends now, found only by argument-dependent lookup on a wx type;
|
||||
"preventing them from implicitly being used with types convertible to wx types"
|
||||
(`changes.txt:185-189`). `char + std::wstring + …` compiled under 3.1.5 through the global
|
||||
(`changes.txt:217-221`). `char + std::wstring + …` compiled under 3.1.5 through the global
|
||||
`operator+(char, const wxString&)`, converting the `std::wstring` implicitly; under 3.3 that
|
||||
operator is a hidden friend (`include/wx/string.h:2150`) and no operand is a `wxString`, so it
|
||||
does not.
|
||||
@@ -413,9 +425,9 @@ change, its line, and what it means for Orca.
|
||||
|
||||
## 5 3.3.0 notable changes
|
||||
|
||||
`changes.txt:380-592` (relative to 3.2.8).
|
||||
`changes.txt:573-785` (relative to 3.2.8).
|
||||
|
||||
**Major changes** (:385-394)
|
||||
**Major changes** (:578-587)
|
||||
|
||||
| Change | Orca relevance |
|
||||
|---|---|
|
||||
@@ -429,7 +441,7 @@ change, its line, and what it means for Orca.
|
||||
| Native GTK file dialogs when possible (#24486, #25104) | the portal dialog is used only with GTK ≥ 3.20 at runtime, without `wxFD_PREVIEW` and without an extra control [source] (`src/gtk/filedlg.cpp:265-273, 438-443`); Orca's `CheckboxFileDialog` (`SetExtraControlCreator`, `GUI_Utils.hpp`) therefore gets the non-native GTK dialog |
|
||||
| Native `wxTextCtrl` contents / RTF (#24626, #24912) | available (`GetRTFValue`, `SearchText`) |
|
||||
|
||||
**All** (:398-442)
|
||||
**All** (:591-635)
|
||||
|
||||
| Change | Orca relevance |
|
||||
|---|---|
|
||||
@@ -439,7 +451,7 @@ change, its line, and what it means for Orca.
|
||||
| Environment variables use UTF-8 (#25101) | check round-tripping of non-ASCII paths through `wxGetEnv`/`wxSetEnv` |
|
||||
| Improved locale matching (#24855); thread-safe `wxPlatformInfo::Get()` (#25459); `wxXmlParseError` from `wxXmlDocument::Load()` (#24215); customisable error exit code (#24770) | available |
|
||||
|
||||
**All (GUI)** (:444-500)
|
||||
**All (GUI)** (:637-693)
|
||||
|
||||
| Change | Orca relevance |
|
||||
|---|---|
|
||||
@@ -452,17 +464,17 @@ change, its line, and what it means for Orca.
|
||||
| Non-live resize restored in wxAUI and `wxSplitterWindow` (#24193) | `wxAUI_MGR_LIVE_RESIZE` is in `wxAUI_MGR_DEFAULT` since 3.3.0 (`interface/wx/aui/framemanager.h:59-66`). The style table's "always enabled in wxGTK3 and wxOSX ports as non-live resizing is not implemented in them" (:199-206) is as stale as the `AlwaysUsesLiveResize()` note: that function "always returns false" as of 3.3.0 (:345; `src/aui/framemanager.cpp:711-714`), and the flag decides on every port [source] (`HasLiveResize`, :716-719). See `webview-gl-aui-media.md` §AUI docking |
|
||||
| `wxInfoBar::ShowCheckBox()` (#25394); printing multiple page ranges (#25030); `wxGrid::CopySelection()` (#24124); new default flat AUI tab art (#25316); `wxApp::SetAppearance()` (#24461) | available |
|
||||
|
||||
**All (WebView)** (:510-525) — `wxWebViewConfiguration` + `GetNativeConfiguration()`, `SetProxy()`,
|
||||
**All (WebView)** (:703-718) — `wxWebViewConfiguration` + `GetNativeConfiguration()`, `SetProxy()`,
|
||||
`ShowDevTools()`, `EnablePersistentStorage()`, `EnableBrowserAcceleratorKeys()`, clearing browsing
|
||||
data, advanced requests, child-window handling, `IsTargetMainFrame()`, Edge user agent settable after
|
||||
creation, and **Edge events queued** (#22744, #19075): Edge handlers run later than on the other
|
||||
backends. Edge posts its events with `AddPendingEvent` (script messages: `src/msw/webview_edge.cpp:811`)
|
||||
except the vetoable ones, `wxEVT_WEBVIEW_NAVIGATING` (:599) and `wxEVT_WEBVIEW_NEWWINDOW` with its
|
||||
`NEWWINDOW_FEATURES` follow-up (:723, :737), which stay synchronous; WebKit and
|
||||
backends. Edge posts its events with `AddPendingEvent` (script messages: `src/msw/webview_edge.cpp:872`)
|
||||
except the vetoable ones, `wxEVT_WEBVIEW_NAVIGATING` (:655-662) and `wxEVT_WEBVIEW_NEWWINDOW` with its
|
||||
`NEWWINDOW_FEATURES` follow-up (:783-785, :796-798), which stay synchronous; WebKit and
|
||||
WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:1360`,
|
||||
`src/gtk/webview_webkit2.cpp:408`) [source]. `webview-gl-aui-media.md` owns the details.
|
||||
|
||||
**wxGTK** (:527-547)
|
||||
**wxGTK** (:720-740)
|
||||
|
||||
| Change | Orca relevance |
|
||||
|---|---|
|
||||
@@ -477,46 +489,53 @@ WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:136
|
||||
| `wxDC::DrawRoundedRectangle()` radius limited to half the smaller side (#24327) | the clamp is in the GTK2 GDK DC (`src/gtk/dcclient.cpp:874-875`, built only in the GTK2 opt-out, `GTK2_LOWLEVEL_SRC` in `build/files`) and also in the common `wxGraphicsPathData::AddRoundedRectangle` (`src/common/graphcmn.cpp:439-440`, absent in 3.1.5) that `wxGraphicsContext::DrawRoundedRectangle` uses, so every `wxGCDC` clamps: GTK3 (Cairo) and macOS window DCs, and Orca's memory-DC + `wxGCDC` paint paths on all ports [source]. A radius larger than half the smaller side is now clamped instead of drawing overlapping arcs |
|
||||
| Read-only `wxBitmapComboBox` height fixed (#25468) | `Slic3r::GUI::BitmapComboBox` on GTK |
|
||||
|
||||
**wxMSW** (:549-583)
|
||||
**wxMSW** (:742-776)
|
||||
|
||||
| Change | Orca relevance |
|
||||
|---|---|
|
||||
| "Enable double buffering for all windows" (#22851) | **reverted in 3.3.2** (#25808) → pitfall below |
|
||||
| `wxOverlay` reimplemented with layered windows (#23261) | none: no `wxOverlay` |
|
||||
| `wxBG_STYLE_TRANSPARENT` implemented (#23412) | as `WS_EX_TRANSPARENT` on non-TLW children [source] (`src/msw/window.cpp:1581-1582`); set before `Create()` (`painting-custom-widgets.md`) |
|
||||
| `wxCAPTION` turned on when min/max/close boxes are set (#23575) | `WS_CAPTION` is added to the style (`src/msw/toplevel.cpp:132-135`); origin of the MainFrame workaround (§8) |
|
||||
| `wxCAPTION` turned on when min/max/close boxes are set (#23575) | `WS_CAPTION` is added to the style (`src/msw/toplevel.cpp:132-135`); origin of the MainFrame workaround (§10) |
|
||||
| `wxButton` default size larger in high DPI (#25297) | raw `wxButton` layouts may grow; Orca dialogs use `Button`/`DialogButtons` |
|
||||
| Markup in `wxStaticText` (#25000); `wxHyperlinkCtrl` colour changeable (#23549) | `SetLabelMarkup` now works on MSW (single line) |
|
||||
| Extended-length paths (#25033); `wxFileDialog` no unwanted extension (#24949); UTF-8 build fixes (#23313); non-BMP strings (#25128) | available |
|
||||
| `wxDisplay` invalidated on display change (#25396); TLW with one child resized on DPI change (#22983); Aero-snapped geometry saved | multi-monitor geometry |
|
||||
| Modern default `wxTreeCtrl` look (#23844); RTL fixes for `wxOverlay`/`wxScrolled` (#25413) and GDI+ (#25431); `wxBitmap::UseAlpha()` returns `bool` (#23919) | available |
|
||||
|
||||
**wxOSX** (:585-592) — `wxEventLoop::OnExit()` is always called (#25409); TLW cursor setting fixed
|
||||
**wxOSX** (:778-785) — `wxEventLoop::OnExit()` is always called (#25409); TLW cursor setting fixed
|
||||
(#25131); Cmd-C no longer activates a "Close" button (#25346); `wxCursor` loadable from resources
|
||||
(#24374); `wxUIActionSimulator` works (#23692), usable for GUI tests.
|
||||
|
||||
**Pitfalls**
|
||||
|
||||
- **Rule:** Do not replace Orca's MSW dark mode with wx's (`SetAppearance`/`MSWEnableDarkMode`)
|
||||
unless live theme switching is kept.
|
||||
**Why:** wx's MSW dark mode cannot change once any top-level window exists or a mode was chosen:
|
||||
`SetAppearance` returns `CannotChange` (`src/msw/darkmode.cpp:263-270`;
|
||||
`interface/wx/app.h:1166-1173`). TaskDialog-based dialogs (`wxMessageDialog`, `wxProgressDialog`,
|
||||
simple `wxAboutBox`), the common dialogs (colour, find/replace, font, page setup, print) and the
|
||||
date/time/calendar controls stay light (`interface/wx/app.h:1434-1448`). Orca switches themes at
|
||||
runtime, which is why 8248b06337 kept NppDarkMode and only informs wx with
|
||||
`MSWEnableDarkMode(DarkMode_Auto)` (§8).
|
||||
- **Rule:** Orca keeps its own Windows theming (`NppDarkMode`) and only informs wx with
|
||||
`MSWEnableDarkMode(DarkMode_Auto)`; do not replace it with wx's dark mode without accounting for the
|
||||
chrome NppDarkMode themes itself.
|
||||
**Why:** when 8248b06337 landed (3.3.2), wx's MSW dark mode could not be changed once a top-level
|
||||
window existed — `SetAppearance` returned `CannotChange` — so a live Preferences toggle would have
|
||||
been restart-only. That blocker is gone: 3.3.3 (#26516) and 3.3.4 (#26734) made the mode switchable
|
||||
at runtime. `MSWEnableDarkMode()` re-applies the mode to an existing window (sends it
|
||||
`WM_SYSCOLORCHANGE`, `src/msw/darkmode.cpp:345-349`), controls restyle through
|
||||
`wxMSWDarkMode::HasChanged()`/`NotifySysColorChange()` (`src/msw/window.cpp:5337, 5528-5534`), and
|
||||
`SetAppearance()` returns only `Ok`/`Failure`; `AppearanceResult::CannotChange` is no longer
|
||||
returned (`src/msw/darkmode.cpp:289-375`; `interface/wx/app.h:1151, 1179-1183`). The remaining
|
||||
documented limits are the date/time/calendar controls, `wxPrintDialog` on Windows 10 and MDI
|
||||
applications (`interface/wx/app.h:1442-1448`); `wxMessageDialog` (3.3.3, #26570) and the common
|
||||
dialogs (3.3.4, #26780) now do support dark mode. Orca still keeps NppDarkMode because it themes
|
||||
Orca's own chrome (title bars, explorer theme, scrollbars, list headers) and drives the live
|
||||
theme-switch path (§10).
|
||||
Cite: 8248b06337 (PR text); `colours-dark-mode.md`.
|
||||
|
||||
- **Rule:** On MSW, a custom-painted control buffers its own drawing (`wxAutoBufferedPaintDC`/
|
||||
`wxBufferedPaintDC` with `wxBG_STYLE_PAINT`, or the Orca memory-DC + `wxGCDC` path), or calls
|
||||
`SetDoubleBuffered(true)` after creation.
|
||||
**Why:** 3.3.0's global `WS_EX_COMPOSITED` was reverted in 3.3.2 (`changes.txt:308`). In 3.3.2
|
||||
**Why:** 3.3.0's global `WS_EX_COMPOSITED` was reverted in 3.3.2 (`changes.txt:501`). In 3.3.4
|
||||
nothing sets it except an explicit `SetDoubleBuffered(true)` [source] (`src/msw/window.cpp:4704-4721`;
|
||||
the only other use is `MSWDisableComposited`, :1643-1652), so MSW windows are not double-buffered by
|
||||
default, exactly as in 3.1.5. `wxAutoBufferedPaintDC` is a `wxBufferedPaintDC` on MSW at compile
|
||||
time (`include/wx/dcbuffer.h:18-23, 215-221`). Nothing tuned against 3.3.0/3.3.1 applies.
|
||||
Cite: `docs/changes.txt:308, 557`; `painting-custom-widgets.md`.
|
||||
Cite: `docs/changes.txt:501, 750`; `painting-custom-widgets.md`.
|
||||
|
||||
- **Rule:** A `wxEVT_DPI_CHANGED` handler must be correct on GTK3, and every handler you bind — on a
|
||||
child, a control or a `DPIDialog`/`DPIFrame` — calls `Skip()`.
|
||||
@@ -529,11 +548,11 @@ WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:136
|
||||
ctor starts at 1 because `get_dpi_for_window` returns 96 on Linux). Double scaling when a window moves between monitors of
|
||||
different scale is a risk that has not been verified at runtime; test DPI changes on GTK when
|
||||
touching `DPIAware::rescale` paths.
|
||||
Cite: `docs/changes.txt:541`; `dpi-bitmaps-fonts.md` §wxEVT_DPI_CHANGED.
|
||||
Cite: `docs/changes.txt:734`; `dpi-bitmaps-fonts.md` §wxEVT_DPI_CHANGED.
|
||||
|
||||
## 6 3.3.1 notable fixes
|
||||
|
||||
`changes.txt:333-377`.
|
||||
`changes.txt:526-570`.
|
||||
|
||||
| Port | Change | Orca relevance |
|
||||
|---|---|---|
|
||||
@@ -547,7 +566,7 @@ WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:136
|
||||
|
||||
## 7 3.3.2 notable changes
|
||||
|
||||
`changes.txt:255-318`, relative to 3.2.10 (see §1 for the unlisted 3.2.9/3.2.10 fixes).
|
||||
`changes.txt:448-511`, relative to 3.2.10 (see §1 for the unlisted 3.2.9/3.2.10 fixes).
|
||||
|
||||
| Port | Change | Orca relevance |
|
||||
|---|---|---|
|
||||
@@ -589,7 +608,7 @@ WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:136
|
||||
// Wrong: m_static_valid->SetLabel(info_line); m_static_valid->Wrap(FromDIP(300));
|
||||
// Right: m_static_valid->SetLabel(info_line); m_static_valid->Wrap(-1); m_static_valid->Wrap(FromDIP(300));
|
||||
```
|
||||
Cite: `docs/changes.txt:280`; `sizers-layout.md` §wxStaticText wrapping.
|
||||
Cite: `docs/changes.txt:473`; `sizers-layout.md` §wxStaticText wrapping.
|
||||
|
||||
- **Rule:** On Linux/X11, call `wxGLCanvas::PreferGLX()` before any GL use, attribute objects
|
||||
included; set a swap interval explicitly if the canvas needs VSync.
|
||||
@@ -605,7 +624,7 @@ WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:136
|
||||
```cpp
|
||||
// Right (if frame pacing is wanted): canvas->SetSwapInterval(1); // before the first SwapBuffers
|
||||
```
|
||||
Cite: `docs/changes.txt:275-276, 292`; `webview-gl-aui-media.md` §EGL vs GLX.
|
||||
Cite: `docs/changes.txt:468-469, 485`; `webview-gl-aui-media.md` §EGL vs GLX.
|
||||
|
||||
- **Rule:** Do not count clicks from `wxEVT_LEFT_DCLICK` alone on macOS; handle `DOWN` and `DCLICK`
|
||||
as on MSW.
|
||||
@@ -613,13 +632,68 @@ WebKit2GTK deliver script messages synchronously (`src/osx/webview_webkit.mm:136
|
||||
(left and right buttons), so a triple click gives `DOWN, DCLICK, DOWN` as on MSW; previously every
|
||||
click with `clickCount > 1` was a `DCLICK` [source] (`src/osx/cocoa/window.mm:4103-4150`). Per-platform click-count ifdefs
|
||||
written for 3.1.5 need rechecking.
|
||||
Cite: `docs/changes.txt:316`; `mouse-keyboard-focus.md`.
|
||||
Cite: `docs/changes.txt:509`; `mouse-keyboard-focus.md`.
|
||||
|
||||
## 8 Migration already done in Orca
|
||||
## 8 3.3.3 notable changes
|
||||
|
||||
The upgrade landed as 8248b06337 ("Updated wxWidgets to 3.3.2", #12941; build system 2d7e26292b).
|
||||
Its PR kept Orca's own MSW dark mode to avoid broader changes and because wx's needs an app restart to
|
||||
switch. Each row is a rule for new code; the owning file has the detail.
|
||||
`changes.txt:388-445`, relative to 3.2.11 (see §1 for the unlisted 3.2.10/3.2.11 fixes).
|
||||
|
||||
| Port | Change | Orca relevance |
|
||||
|---|---|---|
|
||||
| All | `wxMoveToTrash()` (#26256); `wxSizer::DetachItem()` (#26512); truncated reads are errors in `wxDataInputStream` (#26600); `wxGetOsDescription()` (#26231); C++20 `<=>` for `wxString` (#26306) | available; Orca detaches windows and has its own file deletion |
|
||||
| All | **`wxGetTranslation()` returns `const wxString&` again**, reverting 3.3.2's by-value change | the by-value rule is retired → §3 pitfall |
|
||||
| GUI | `wxWebView::Print()` print settings (#26239) and `PrintToPDF()` (#26583); `wxWebViewConfiguration::DisableGPUAcceleration()` (#26626) | `webview-gl-aui-media.md` |
|
||||
| GUI | `wxGrid::GetFrozen{Row,Col}LabelWindow()` (#26617); `wxSVGFileDC` accessibility (#26379) and `GetSVGDocument()` (#26344) | `controls-dataview.md`; `wxSVGFileDC` available |
|
||||
| wxGTK | Fix regression when using `wxImageList` in high DPI (#26349) | the physical-pixel image-list rule is unchanged (§3) |
|
||||
| wxGTK | Fix `wxStaticText` label wrapping | the base `Wrap()` cache is unchanged (§7); only the GTK label wrapping was fixed |
|
||||
| wxGTK | Assert when the clipboard has non-ASCII targets fixed (#26263); GTK-without-Wayland build fixed (#26269); high-DPI bitmaps in `wxAboutBox` (#22192) | clipboard |
|
||||
| wxMSW | **Light/dark mode switching implemented** (#26516) | see §5: this removes the old "cannot switch at runtime" blocker |
|
||||
| wxMSW | `wxMessageDialog` dark mode (#26570); combo/listbox dark mode on Windows 11 (#26535); `wxCheckBox` label in screen readers (#26270); `wxPD_CAN_SKIP` regression (#26287); Direct2D text regression (#26259) | dark-mode and accessibility fixes |
|
||||
| wxMSW | Stylus events (#26223); colour emoji via Direct2D (#26657) | available |
|
||||
| wxOSX | Data-view icons under macOS 26 (#26374); `wxOverlay` phantoms in Mission Control (#26380); `wxEVT_DATAVIEW_ITEM_EDITING_DONE` value set (#26367); Xcode project for macOS 27 (#26578) | native look and data view |
|
||||
|
||||
## 9 3.3.4 notable changes
|
||||
|
||||
`changes.txt:295-385`, relative to 3.2.11 (see §1 for the unlisted 3.2.11/3.2.12 fixes).
|
||||
|
||||
| Port | Change | Orca relevance |
|
||||
|---|---|---|
|
||||
| All | `wxString` usable with `{fmt}`/`std::format()` (#27180); `wxPATH_RMDIR_PARENTS`; `fsync()` in `wxTempFile` (#27001); `wxDateTime::GetAsDOS()` after 2038 (#4393); TCP `wxIPC` fixes (#24858) | available |
|
||||
| GUI | **Accelerators take priority over the focused window in all ports** (#22630), with the new `wxEVT_ACCELERATOR_KEY` event and the `wxWindow::ClaimsKeyBeforeAccelerator()` override that text controls use to reserve their editing keys (`interface/wx/event.h:1799`, `interface/wx/window.h:4580`) | pitfall below; `mouse-keyboard-focus.md` |
|
||||
| GUI | wxGrid: `wxGridCellChoiceEditor` UI fixes (#12094), best size for auto-wrapped rows (#14072), `MakeCellVisible()` with variable row heights (#4371), editor-change crash (#21986) | `controls-dataview.md`; the choice-editor `Combo()` cast rule is unchanged |
|
||||
| GUI | AUI: no spurious sash jump on click (#4547); an added pane's best size is respected (#4404) | Plater docking |
|
||||
| GUI | `wxListCtrl` (#15411) and `wxStatusBar` (#24305) accessibility; `wxAuiNotebook` selection after a page removal (#9920); `wxPreviewCanvas` crash (#9822); generic `wxCalendarCtrl` background colour (#21885); LunaSVG with filters (#27176) | available; no `wxAuiNotebook` in Orca |
|
||||
| wxMSW | **Dark mode can be enabled dynamically** (#26734); dark mode for `wxFontPickerCtrl` (#26667), `wxNotebook` (#26694, #26695), `wxSpinButton` (#26682, #26683) and the common dialogs (#26780) | §5 pitfall; `colours-dark-mode.md` |
|
||||
| wxMSW | `wxRenameFile()` no longer copies file attributes (`changes.txt:345-347`, incompatible); Esc closes dialogs used by IME/auto-completion (#16059, #27145); IME handling in wxGrid improved (#24558); `wxPersistent` controls DPI-aware (#18752); non-BMP character input (#27016) | file dialogs, keyboard and IME |
|
||||
| wxGTK | Wayland: crash on pointer/seat disconnect fixed (#27069); **AUI panes draggable via system drag sessions** (#26969); **window geometry restorable** via XDG session management (#26324); overlay-scrollbar client size (#26889) | the Wayland gaps are partly narrowed; `webview-gl-aui-media.md` §AUI |
|
||||
| wxOSX | `wxEVT_CHAR` key codes fixed for events with Ctrl (#26810); context-menu accessibility (#13010); custom controls in sandboxed `wxFileDialog` (#26908) | `mouse-keyboard-focus.md`; macOS keys |
|
||||
|
||||
**Pitfalls**
|
||||
|
||||
- **Rule:** On every port an accelerator now runs before the focused window handles the key, unless
|
||||
that window claims the key; a custom control that must keep a key over an accelerator overrides
|
||||
`wxWindow::ClaimsKeyBeforeAccelerator()`, or handles `wxEVT_ACCELERATOR_KEY` and calls
|
||||
`UseAccelerator()`.
|
||||
**Why:** before 3.3.4 only wxGTK let the focused window handle the key first; the other ports
|
||||
already gave accelerators priority. 3.3.4 made every port consistent and added the
|
||||
`wxEVT_ACCELERATOR_KEY` event, sent after `wxEVT_CHAR_HOOK` (before it on macOS) to the focus
|
||||
window and propagated to its parents (`interface/wx/event.h:1740-1801`;
|
||||
`interface/wx/window.h:4554-4583`). Text controls, `wxComboBox` and `wxSpinCtrl` reserve their
|
||||
editing keys by overriding `ClaimsKeyBeforeAccelerator()` and returning
|
||||
`wxTextEntryBase::IsUsedForEditing()` (`src/common/textcmn.cpp:136-140`;
|
||||
`src/common/textentrycmn.cpp:441-509`; `src/common/spinctrlcmn.cpp:160-167`;
|
||||
`src/msw/combobox.cpp:389-395`, `src/gtk/combobox.cpp:205-211`), and the GTK accelerator walk now
|
||||
consults it (`src/gtk/window.cpp:1524-1539`). Orca's topbar menus are popups whose accelerators are
|
||||
display-only and Orca dispatches its own shortcuts, so few sites are affected; the macOS
|
||||
`ObjectList` `wxAcceleratorTable` and the wxInspector table are the live ones.
|
||||
Cite: `docs/changes.txt:321`; `mouse-keyboard-focus.md` §Accelerators.
|
||||
|
||||
## 10 Migration already done in Orca
|
||||
|
||||
The upgrade landed as 8248b06337 ("Updated wxWidgets to 3.3.2", #12941; build system 2d7e26292b) and
|
||||
the pin later advanced to upstream 3.3.4. Its PR kept Orca's own MSW dark mode to avoid broader
|
||||
changes; wx could then only switch at app start, so a live Orca toggle needed NppDarkMode. Each row is
|
||||
a rule for new code; the owning file has the detail.
|
||||
|
||||
| Commit | Rule for new code | Where | Owner |
|
||||
|---|---|---|---|
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
diff --git a/build/cmake/wxWidgetsConfig.cmake.in b/build/cmake/wxWidgetsConfig.cmake.in
|
||||
index 2f3a735d920c..2593c045b89b 100644
|
||||
--- a/build/cmake/wxWidgetsConfig.cmake.in
|
||||
+++ b/build/cmake/wxWidgetsConfig.cmake.in
|
||||
@@ -50,12 +50,28 @@ if(WIN32_MSVC_NAMING)
|
||||
set(wxARCH_SUFFIX "_${wxPLATFORM_ARCH}")
|
||||
endif()
|
||||
|
||||
- # use wxWidgets_USE_STATIC to force static libraries, otherwise shared is searched first
|
||||
- if(NOT wxWidgets_USE_STATIC AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/${wxCOMPILER_PREFIX}${wxARCH_SUFFIX}_dll/@PROJECT_NAME@Targets.cmake")
|
||||
- set(wxPLATFORM_LIB_DIR "/${wxCOMPILER_PREFIX}${wxARCH_SUFFIX}_dll")
|
||||
- elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${wxCOMPILER_PREFIX}${wxARCH_SUFFIX}_lib/@PROJECT_NAME@Targets.cmake")
|
||||
- set(wxPLATFORM_LIB_DIR "/${wxCOMPILER_PREFIX}${wxARCH_SUFFIX}_lib")
|
||||
+ # wxCOMPILER_PREFIX names the consuming compiler; the installed layout is named
|
||||
+ # after the compiler that built wxWidgets. cl and clang-cl share an ABI, so
|
||||
+ # either can consume either build.
|
||||
+ set(wxCOMPILER_PREFIXES "${wxCOMPILER_PREFIX}")
|
||||
+ if(wxCOMPILER_PREFIX STREQUAL "clang")
|
||||
+ list(APPEND wxCOMPILER_PREFIXES "vc")
|
||||
+ elseif(wxCOMPILER_PREFIX STREQUAL "vc")
|
||||
+ list(APPEND wxCOMPILER_PREFIXES "clang")
|
||||
endif()
|
||||
+
|
||||
+ # use wxWidgets_USE_STATIC to force static libraries, otherwise shared is searched first
|
||||
+ foreach(wxPREFIX IN LISTS wxCOMPILER_PREFIXES)
|
||||
+ if(NOT wxWidgets_USE_STATIC AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/${wxPREFIX}${wxARCH_SUFFIX}_dll/@PROJECT_NAME@Targets.cmake")
|
||||
+ set(wxPLATFORM_LIB_DIR "/${wxPREFIX}${wxARCH_SUFFIX}_dll")
|
||||
+ break()
|
||||
+ elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${wxPREFIX}${wxARCH_SUFFIX}_lib/@PROJECT_NAME@Targets.cmake")
|
||||
+ set(wxPLATFORM_LIB_DIR "/${wxPREFIX}${wxARCH_SUFFIX}_lib")
|
||||
+ break()
|
||||
+ endif()
|
||||
+ endforeach()
|
||||
+ unset(wxPREFIX)
|
||||
+ unset(wxCOMPILER_PREFIXES)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}${wxPLATFORM_LIB_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
Vendored
+8
-2
@@ -28,12 +28,18 @@ if (APPLE)
|
||||
COMMAND ${GIT_EXECUTABLE} apply --verbose
|
||||
${CMAKE_CURRENT_LIST_DIR}/0001-macos-use-srgb-colour-components.patch
|
||||
)
|
||||
elseif (WIN32)
|
||||
set(_wx_patch_command
|
||||
${GIT_EXECUTABLE} checkout -f -- build/cmake/wxWidgetsConfig.cmake.in
|
||||
COMMAND ${GIT_EXECUTABLE} apply --verbose
|
||||
${CMAKE_CURRENT_LIST_DIR}/0002-clang-cl-sibling-compiler-prefix.patch
|
||||
)
|
||||
endif ()
|
||||
|
||||
orcaslicer_add_cmake_project(
|
||||
wxWidgets
|
||||
GIT_REPOSITORY "https://github.com/SoftFever/Orca-deps-wxWidgets"
|
||||
GIT_TAG v3.3.2
|
||||
GIT_REPOSITORY "https://github.com/wxWidgets/wxWidgets"
|
||||
GIT_TAG v3.3.4
|
||||
GIT_SHALLOW ON
|
||||
GIT_SUBMODULES 3rdparty/catch 3rdparty/pcre 3rdparty/libwebp
|
||||
PATCH_COMMAND ${_wx_patch_command}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -118,9 +118,9 @@ modules:
|
||||
# Use git instead of archive: wxWidgets 3.3 relies on multiple git
|
||||
# submodules (PCRE2, etc.) that are not included in GitHub tarballs.
|
||||
- type: git
|
||||
url: https://github.com/SoftFever/Orca-deps-wxWidgets.git
|
||||
tag: orca-3.3.2
|
||||
commit: db1005db3dea2c37a46fb455a9a02e37aa360751
|
||||
url: https://github.com/wxWidgets/wxWidgets.git
|
||||
tag: v3.3.4
|
||||
commit: 6a42a4b999b127cf28a8b5fe686da6b8ca93a9b8
|
||||
|
||||
# OrcaSlicer C++ dependencies (built offline with pre-downloaded archives)
|
||||
- name: orca_deps
|
||||
|
||||
@@ -379,14 +379,24 @@ void FilamentGroupPopup::OnTimer(wxTimerEvent &event)
|
||||
// leaving event got triggered. So the timer is stopped first, then started
|
||||
// again, causing the popup being dismissed immediately.
|
||||
// To fix this, we check if cursor is still inside the popup window before
|
||||
// dismissing.
|
||||
// dismissing, and keep checking while it is: a leave event is not guaranteed
|
||||
// to follow, and a popup left open keeps grabbing the mouse capture.
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (this->GetClientRect().Contains(pos)) return;
|
||||
if (this->GetClientRect().Contains(pos)) {
|
||||
StartTimer();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Dismiss();
|
||||
}
|
||||
|
||||
FilamentGroupPopup::~FilamentGroupPopup()
|
||||
{
|
||||
m_timer->Stop();
|
||||
delete m_timer;
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::Dismiss() {
|
||||
m_active = false;
|
||||
PopupWindow::Dismiss();
|
||||
@@ -405,7 +415,10 @@ void FilamentGroupPopup::OnEnterWindow(wxMouseEvent &)
|
||||
// Ignore spurious ENTER synthesized by PopupWindow::OnMouseEvent2 on macOS.
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (!this->GetClientRect().Contains(pos)) return;
|
||||
// On macOS the timer keeps running instead, and OnTimer closes the popup once the cursor has left it.
|
||||
#ifndef __APPLE__
|
||||
ResetTimer();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::UpdateButtonStatus(int hover_idx)
|
||||
|
||||
@@ -27,6 +27,7 @@ class FilamentGroupPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
FilamentGroupPopup(wxWindow *parent);
|
||||
~FilamentGroupPopup() override;
|
||||
void tryPopup(Plater* plater,PartPlate* plate, bool slice_all);
|
||||
void tryClose();
|
||||
void Dismiss() override;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/dialog.h>
|
||||
#include "slic3r/GUI/FilamentMapPanel.hpp"
|
||||
#include "slic3r/GUI/FilamentGroupPopup.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
@@ -377,6 +379,13 @@ FilamentMapMode FilamentMapDialog::get_mode()
|
||||
|
||||
int FilamentMapDialog::ShowModal()
|
||||
{
|
||||
// The Slice-plate hover popup is a transient popup that keeps grabbing the mouse
|
||||
// capture while shown. Left behind this modal dialog it would starve the dialog of
|
||||
// mouse events, so close it synchronously first, whichever path opened the dialog.
|
||||
if (MainFrame* frame = wxGetApp().mainframe;
|
||||
frame && frame->m_filament_group_popup && frame->m_filament_group_popup->IsShown())
|
||||
frame->m_filament_group_popup->Dismiss();
|
||||
|
||||
update_panel_status(m_page_type);
|
||||
return wxDialog::ShowModal();
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ void GridCellFilamentsEditor::SetSize(const wxRect& rect)
|
||||
|
||||
void GridCellFilamentsEditor::OnComboCloseUp(wxCommandEvent& evt)
|
||||
{
|
||||
wxGridCellChoiceEditor::OnComboCloseUp(evt);
|
||||
wxGridCellChoiceEditor::DismissEditor();
|
||||
}
|
||||
|
||||
void GridCellFilamentsEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
@@ -449,7 +449,7 @@ void GridCellChoiceEditor::SetSize(const wxRect &rect)
|
||||
wxGridCellChoiceEditor::SetSize(rect);
|
||||
}
|
||||
|
||||
void GridCellChoiceEditor::OnComboCloseUp(wxCommandEvent &evt) { wxGridCellChoiceEditor::OnComboCloseUp(evt); }
|
||||
void GridCellChoiceEditor::OnComboCloseUp(wxCommandEvent &evt) { wxGridCellChoiceEditor::DismissEditor(); }
|
||||
|
||||
void GridCellChoiceEditor::BeginEdit(int row, int col, wxGrid *grid)
|
||||
{
|
||||
|
||||
@@ -2309,12 +2309,6 @@ wxBoxSizer* MainFrame::create_side_tools()
|
||||
|
||||
bool slice = true;
|
||||
|
||||
// The Slice-plate hover popup is a transient popup that keeps grabbing
|
||||
// the mouse capture while shown. Left behind the modal grouping dialog it
|
||||
// would starve that dialog of mouse events, so close it synchronously first.
|
||||
if (m_filament_group_popup)
|
||||
m_filament_group_popup->Dismiss();
|
||||
|
||||
auto curr_plate = m_plater->get_partplate_list().get_curr_plate();
|
||||
#ifdef __linux__
|
||||
PresetBundle* preset = wxGetApp().preset_bundle;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
BEGIN_EVENT_TABLE(SideButton, wxWindow)
|
||||
EVT_LEFT_DOWN(SideButton::mouseDown)
|
||||
EVT_LEFT_UP(SideButton::mouseReleased)
|
||||
EVT_MOUSE_CAPTURE_LOST(SideButton::mouseCaptureLost)
|
||||
EVT_PAINT(SideButton::paintEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -331,20 +332,30 @@ void SideButton::mouseDown(wxMouseEvent& event)
|
||||
event.Skip();
|
||||
pressedDown = true;
|
||||
SetFocus();
|
||||
CaptureMouse();
|
||||
// Capturing twice pushes this button onto the capture stack twice, and the
|
||||
// release would then hand the capture straight back to it.
|
||||
if (!HasCapture())
|
||||
CaptureMouse();
|
||||
}
|
||||
|
||||
void SideButton::mouseReleased(wxMouseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
// A press whose release went elsewhere still holds the capture.
|
||||
if (HasCapture())
|
||||
ReleaseMouse();
|
||||
if (pressedDown) {
|
||||
pressedDown = false;
|
||||
ReleaseMouse();
|
||||
if (wxRect({0, 0}, GetSize()).Contains(event.GetPosition()))
|
||||
sendButtonEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void SideButton::mouseCaptureLost(wxMouseCaptureLostEvent&)
|
||||
{
|
||||
pressedDown = false;
|
||||
}
|
||||
|
||||
void SideButton::sendButtonEvent()
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
|
||||
|
||||
@@ -94,6 +94,7 @@ private:
|
||||
|
||||
void mouseDown(wxMouseEvent& event);
|
||||
void mouseReleased(wxMouseEvent& event);
|
||||
void mouseCaptureLost(wxMouseCaptureLostEvent& event);
|
||||
|
||||
void sendButtonEvent();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user