This is not necessary any longer after the changes of the parent commit.
This is a partial revert of 59bdee5558 (Fix handling of Esc while an
auto-complete drop down is open in wxMSW., 2014-03-08), see #13945.
Generating wxEVT_CHAR_HOOK for "Esc" presses from the keyboard hook
resulted in multiple problems with IME (see #11386 and #22473 that were
already worked around as well as still open #27145) or other controls
that need to handle "Esc" themselves (see #9102 and #13945 for which we
added the workarounds and #16059 which is still open too).
Solve all of these issues by postponing wxEVT_CHAR_HOOK generation for
this key until later, when the message is already being processed. This
should avoid all such problems at the price of not generating these
events at all in some scenarios, e.g. when a native control really wants
Esc for itself or when wx is used in a modeless dialog in a plugin DLL
and its event loop is not running.
Hopefully this shouldn't be important in practice but this change should
avoid having any more problems with various IMEs.
Closes#16059.
Closes#27145.
Extract this function from the keyboard hook to allow its reuse in
upcoming commits.
No real changes yet.
This commit is best viewed ignoring whitespace-only changes.
By convention, wxHAS_XXX symbols should be defined or not, unlike
wxUSE_XXX ones that are always defined as either 1 or 0.
Change wxHAS_2CHAR_NEWLINES definition and tests for it to follow this
rule.
No real changes.
The recent 07590bec33 (Use preceding label as accessibility title of
controls under macOS, 2026-09-21) started calling GetLabel() from
MacPostControlCreate() which is called before the object was fully
constructed and could (and did) result in crashes due to the use of the
not yet initialized members.
Avoid this by adding a new HasAccessibilityTitle() virtual function of
wxWidgetImpl which is fully constructed by the time this function is
used and also addresses the question of whether the preceding label
should be used as this window accessibility title more precisely.
See #27060, #27140.
Closes#27142.
This compiler started giving -Wnontrivial-memcall for using memset()
with non-trivially copyable type wxLZMAStream, so avoid it by using
LZMA_STREAM_INIT instead, which is meant to be used exactly for this.
wxAuiFloatingFrame could receive wxEVT_SIZE during its destruction, even
if it was already hidden, and handling these events crashed due to
dereferencing dangling wxSizerItem pointers.
Fix this by overriding wxAuiFloatingFrame::Destroy() to perform the
necessary cleanup when the frame is about to be destroyed.
Add wxAuiManager::DestroyFloatingFrame() helper which makes the code say
more clearly what it does -- this is not required to fix the bug but
affects the same code, so do it in the same commit.
Also add a unit test confirming that destroying the floating frame in
various ways doesn't crash any longer.
Closes#26264.
Originally-by: alilie <alexandru.ilie@hexagon.com>
Since the changes of f11053a2d3 (Fix copy/paste in wxGTK when a
clipboard manager is running, 2026-03-09) we were accumulating all
data passed to wxClipboard::AddData() because we never cleared the list
of targets in the active selection any more.
This resulted in a crash under WSL (probably due to overflowing some
implementation limits) and must have been problematic elsewhere too, so
stop doing this and do clear the list of targets before setting new
ones.
Still don't call wxClipboard::Clear() neither from AddData() nor from
SetData() to avoid reintroducing the original problem fixed by the
commit above.
See #26265, #26278.
Closes#27102.
Co-authored-by: Eran Ifrah <eran@codelite.org>
Retry the clipboard operation if the clipboard happens to be busy
(because another application or the system is using it) just at the time
when we need it.
This should avoid spurious errors in CMake MSW CI jobs which are
probably due to the fact that multiple tests using clipboard may be
running in parallel now, but also seems to be useful for the real
applications which might run into the same problem, so fix it at the
library level rather than in the test.
This amends the recent 49d8a0c6f8 (Make ListCtrl::ColumnDrag unit test
more robust, 2026-09-28) to wait for just the last event as this is all
we need for the test and we don't really need to wait for each event.
This is the case for console applications and it was broken by binding
to GetWindowSubclass() import of comctl32.dll by name because it's not
present in v5 of the DLL which is used in absence of the manifest,
resulting in the executable being unable to start.
Apply a local fix to this by loading this function during run-time, when
we can be sure that we're using v6 which does export it by name (v5 only
exports it by ordinal 411).
Closes#27114.
Extract code duplicated in wxWidgetCocoaImpl::SetAccessibilityLabel()
and SetAccessibilityTitleElement() into a new function.
No real changes.
See #27056, #27060.
In dark mode wxListCtrl draws its items itself and decides whether an
item is hot from the mouse position at the time it is painted. But when
the control scrolls, the native control moves the rows that are already
drawn instead of repainting them, and doesn't invalidate anything for
the hot item if the mouse didn't move.
Scrolling with the keyboard while the mouse is over the control
therefore leaves a trail: the row drawn as hot keeps its highlight at
its new position, and the row that is now under the mouse is drawn as
hot too, so every row that passes under the mouse stays highlighted.
Refresh the control when a message that can scroll it did change the
top item.
Closes#27112.
Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
Gallery items have just a bitmap, an ID and the application's client
data, so there is nothing a screen reader can announce for them and they
are read as "list item 3 of 39", which is useless.
Add Append(bitmap, id, label) and Set/GetItemLabel() and use the label
as the accessible name of the item. The label is not drawn, as the items
of a gallery are bitmaps by design, it only exists to be announced. It
could also be used for tooltips later, which the items don't have
either.
The ribbon sample already knows the names of the colours it puts in its
galleries, so it passes them as the labels now, which also makes them a
useful test case.
Closes#27100.
Use the new API, i.e. call ClaimsKeyBeforeAccelerator() and send
wxEVT_ACCELERATOR_KEY, in wxQt too.
Update wxComboBox to override ClaimsKeyBeforeAccelerator() too.
Note that wxTextCtrl and wxSpinCtrl don't need to be modified because
they already do this in the base class.
This actually simplifies the existing code as we don't need
wxWindow::m_processingShortcut any more.
Use the new API, i.e. call ClaimsKeyBeforeAccelerator() and send
wxEVT_ACCELERATOR_KEY, in wxOSX too, whenever possible, i.e. not for
Cmd-Letter used by the menu items as we never get key events for them at
all.
This probably could be worked around by overriding performKeyEquivalent:
but for now leave it like this because hopefully there should be no
conflict between menu accelerators and standard text editing keys as
Cmd+C etc act on the focused window anyhow by default, so the behaviour
should be already correct anyhow.
When deciding whether a key press should trigger an accelerator or be
handled by the currently focused window different ports behaved
differently, with wxGTK always prioritizing the focused window and the
other ports giving priority to the accelerator, and neither of them
allowed customizing this.
Change this now by introducing 2 ways to do it: first, a window can
override new ClaimsKeyBeforeAccelerator() virtual function to specify
which keys it wants to handle itself, even if they correspond to an
accelerator. And second, send wxEVT_ACCELERATOR_KEY event which can be
handled by the application, typically centrally in its wxFrame-derived
class, to decide if it wants some accelerator that it defines to not
steal the key from the window or, on the contrary, to always do it, even
if the window overrides ClaimsKeyBeforeAccelerator() as wxTextCtrl does.
Note that while ClaimsKeyBeforeAccelerator() replaces some uses of
wxMSW-specific MSWShouldPreProcessMessage(), but it's still needed to
prevent the key getting eaten by IsDialogMessage().
This is not a backwards-compatible change as it changes the default
wxGTK behaviour, but it is now compatible with the other ports and can
be easily customized if necessary.
This commit only implements this for wxMSW and wxGTK, other ports will
be updated too soon.
Changes of 7148a49c6d (Map wxDF_TEXT to text in UTF-8 encoding in wxOSX,
2026-06-06) were incomplete and left wxDataFormat::SetId() inconsistent
with GetFormatForType() for wxDF_TEXT, which resulted in producing
UTF-16 text when asked for "public.utf8-plain-text" as is the case when
drag-and-dropping text to the Terminal.
Fix this by simply mapping kUTTypeUTF8PlainText to wxDF_TEXT here too.
Closes#26972.
The sample hardcodes white background for the frame, but the default
text colour in dark mode is also white, which made it invisible.
Fix this by hardcoding the text colour too.
The list of the keys which are used for editing the text and which
shouldn't be taken by the accelerators using the same keys existed only
in wxMSW and only as a function taking a MSG, move it to the common code
as wxTextEntryBase::IsUsedForEditing() taking wxKeyEvent, as it is going
to be needed by the other ports too in the upcoming commits.
Note that this also slightly changes wxMSW behaviour because the keys
producing printable characters, as well as Backspace, are now considered
as being used for editing too and so are not passed to the accelerators
any longer, which seems more correct as typing text in a control
shouldn't trigger the accelerators using the same keys.
It was previously available only in the generic version which was used
by wxGTK and wxUniv, add it to the other ports too as it's going to be
needed in the upcoming commit.
In wxMSW this required storing the accelerators, as it is simpler than
converting them back from the native HACCEL and more consistent with the
other ports that already did this.
Add the new function checking if a (key) event and wxAcceleratorEntry
correspond to the same key combination.
This was already used in the generic wxAccelerator implementation and
wxOSX and will be used in the other ports too soon, so move this code
into common function.
It can also be useful for the applications, so document it as well.
This avoids
CMake Warning at build/cmake/init.cmake:710 (find_package):
By not providing "FindSDL3.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "SDL3", but
CMake did not find one.
...
which is not just useless but also misleading because FindSDL3.cmake
doesn't exist (only config mode is supported by SDL3).
See #26773.
Closes#27062.
MSW cross-builds / wxMSW 64 bits not compatible (push) Canceled after 0s
MSW cross-builds / wxMSW/Univ (push) Canceled after 0s
MSW cross-builds / wxMSW 32 bits (push) Canceled after 0s
Code Checks / Check Spelling (push) Canceled after 0s
Code Checks / Check Whitespace (push) Canceled after 0s
Code Checks / Check Mixed EOL (push) Canceled after 0s
Code Checks / Check C++ Style (push) Canceled after 0s
Code Checks / Check All Headers In allheaders.h (push) Canceled after 0s
Update Documentation / Update Online Documentation (push) Canceled after 0s
The registry key used by this function under MSW can be absent (at least
when using Wine), but this is not really an error, so don't log it.
Closes#27067.
At least in macOS CI jobs something can be listening on 8081, making the
CI run fail when this happens, so choose a port randomly and try a few
adjacent ports if the random port doesn't work.
This should hopefully avoid spurious CI failures when go-httpbin can't
start.
"go install" sporadically fails to get go-httpbin, avoid failing the CI
run if this happens.
This is not ideal because if it starts always failing, the tests could
get broken without anybody noticing, but it's just too annoying
otherwise.
Force creating the system menu to ensure that its handle belongs to this
process and not to Explorer, for example, as it is apparently owned by
the process which calls GetSystemMenu() first.
Closes#26799.
MSW cross-builds / wxMSW 64 bits not compatible (push) Canceled after 0s
MSW cross-builds / wxMSW/Univ (push) Canceled after 0s
MSW cross-builds / wxMSW 32 bits (push) Canceled after 0s
Code Checks / Check Spelling (push) Canceled after 0s
Code Checks / Check Whitespace (push) Canceled after 0s
Code Checks / Check Mixed EOL (push) Canceled after 0s
Code Checks / Check C++ Style (push) Canceled after 0s
Code Checks / Check All Headers In allheaders.h (push) Canceled after 0s
Update Documentation / Update Online Documentation (push) Canceled after 0s
In a tree control with wxTR_MULTIPLE style, a click on the already
selected item doesn't start in-place editing if the control had lost
focus since the previous click, as such a click is supposed to just
restore the focus to the control and nothing else.
However the in-place editor itself takes the focus when it is shown,
so this flag remained set after the end of any label edit and the next
click on the item was silently swallowed instead of starting editing
it again, i.e. two clicks were needed to rename the item once more.
Don't set the flag when losing focus to our own editor then, but do
set it from the EN_KILLFOCUS handler if the editor loses focus to
another window, so that clicking back into the control still doesn't
start editing. Also check whether the editor is open in the mouse
click handler itself, as the click dismissing it shouldn't start a new
edit either, which used to be ensured by the same flag.
Assisted-by: Claude Opus 5
When determining the size of a window, GetScrollbarSize() should be used
instead of using the metrics values because the function takes into
account the case of overlay scrollbars, which are used by default with
GTK 3, unlike the metric value.
Also update the documentation to recommend doing this.
It is 0 in the default theme with GTK 3, but may be potentially non-0
even in it too and it's 3 by default with GTK 2, so GetScrollbarSize()
didn't return the correct result there.
Make it work in all cases by ensuring that GetScrollbarSize() and
DoGetClientSize() agree.
The value could have been cached for the size which has changed since it
was computed, making it wrong.
In practice, this resulted in a failure in "ListCtrl::Visible" unit test
in wxGTK when GTK_OVERLAY_SCROLLING=0 was set. This happened because the
initial window size was computed assuming that the scrollbars would be
shown (with overlay scrollbars we never reserve any space for them) and
the value of lines fitting per page became wrong later when it turned
out that no scrollbars were necessary.
The test passes both with and without GTK_OVERLAY_SCROLLING=0 now.
This reverts 4e0fca8ab9 (Fix crash when connection is refused in
wxWebRequestCURL, 2024-10-27) which is not needed any longer after the
underlying bug in wxGTK event loop has been fixed.
See #24885.
It doesn't make sense to continue reporting any events on a source that
has been destroyed, it doesn't need them any more and we could crash
using now dangling pointers and, worse, we could wrongly process the
notifications for a new source reusing the same FD.
This was the root source of multiple problems in wxWebRequestCURL and
could also cause them elsewhere.
Change wxRichTextEvent::m_char to be of type wxUniChar and not wxChar.
This is mildly backwards-incompatible but the break is arguably worth
not adding some new GetUnicodeCharacter().
wxChar can't hold all possible characters under MSW, so prefer using
wxUniChar even if it's not clear if this have any practical benefits in
this particular case.
Recombine the 2 WM_CHAR messages we receive for high and low surrogate
pair into a single Unicode character which can be retrieved using the
new wxKeyEvent::GetUnicodeChar() member function.
Update documentation and comments to recommend using the new function
instead of GetUnicodeKey().
Also update the keyboard sample to use it to be able to show events for
supplementary characters under MSW.
Closes#25135.
Don't show IME when pressing keys in wxDataViewCtrl, this is useless
and confusing because it doesn't accept text input.
This fixes a similar problem to that of #24558 for wxGrid.
Some cells may be editable but not accept text input, e.g.
wxGridCellBoolEditor handles some keys but only to set/clear/toggle the
checkbox it shows, and the IME should not be shown for them.
Avoid adding a new wxGridCellEditor::AcceptsTextInput() virtual function
by reusing the existing IsAcceptedKey() to probe for text input support:
we decide that if "a" is a valid key, then any text can be entered.
If this hack turns out to be too limiting or surprising, we can always
add AcceptsTextInput() later.
See #24558.
Static gs_stdPaths variable may not be initialized yet at this stage and
so an invalid wxStandardPaths object could be created.
Fix this by simply making this global variable static in the only
function using it -- it doesn't need to be global at all and this
ensures that it's initialized before use.
wxConvFileName may not be initialized yet and there is nothing we can do
about this because it has to remain a simple variable to allow setting
it.
However we can change wxConvFile and wxFNCONV to use wxGetFileNameConv()
accessor function which ensures that we initialize wxConvFileName before
using it at least via these functions.
Also update a couple of direct references to wxConvFileName in the code
which might conceivably be used at this stage.
Add wxWindow::UpdateInputMethodCursorRect() which can be used to let the
IME know where to place its window and use it in wxGrid to show it near
the cell being edited.
See #24558.
Update the scroll position before scrolling in wxGTK to make it
consistent with the other ports.
Add a unit test checking that all ports behave consistently.
Implement it in wxMSW, wxGTK and wxOSX.
This will be used to prevent IME window from appearing for windows that
currently don't accept keyboard input even if they accept focus.
Iterate over the animation manually to find the frame we need.
Update the sample to allow showing individual animation frames.
Closes#27009.
Co-authored-by: Vadim Zeitlin <vadim@wxwidgets.org>
Don't consider "C" locale to be UTF-8 except in UTF-8-only build where
it needs to be done to allow the program to run at all.
This fixes a bug when wx CRT wrappers get broken by creating and
destroying wxLocale: initially functions such as wxSnprintf() handle
non-ASCII characters correctly because wxLocaleIsUtf8 is initially
false, so they use wide char functions. But creating and destroying
(any) wxLocale results in wxUpdateLocaleIsUtf8() being called and if the
locale was "C" (as it is by default), it sets wxLocaleIsUtf8 to true
meaning that wxSnprintf() etc now use narrow character functions that
don't handle non-ASCII characters and just fail for them.
Previously wxString::Format("%c", wxUniChar{0x1F600}) produced broken
"\uF600" under MSW because this was all that fit into a wchar_t there
which can only contain 16-bits. And using "%d" or "%x" was broken in the
same way, as wxArgNormalizer<wxUniChar> always used wx_truncate_cast()
to wchar_t which is not lossless when sizeof(wchar_t)==2.
Fix this with the following horrible/ingenuous/crazy (choose your own
adjective) hack: because we can't fit supplementary Unicode characters
into a wchar_t, don't even try doing it and instead inject the bytes
representing the character into the format string itself (suitable
padded/aligned depending on the formatting flags) and replace the
format specifier used for wxUniChar with "%.0d" and feed it 0, which
ensures that no output is produced for it.
This can be done with surprisingly little amount of changes and should
be completely transparent to any code not formatting wxUniChars outside
of the BMP -- while such code will now behave correctly, instead of
silently producing wrong output as before, under MSW too.
Note that we do this unconditionally, i.e. without preprocessor checks
for SIZEOF_WCHAR_T, even if old code worked when it was 4, because using
the same code under all platforms should make finding and fixing bugs in
it simpler and also because this code is already hairy enough to not
need any extra complications.
No real changes yet, just add a function with a name indicating that it
can do more than just validate the format string (because it will soon)
and call it instead of Validate().
While the current and minimum positions were updated, the saved last
split position was not, so unsplitting the splitter, changing the DPI
and splitting it again wouldn't use the correct position for the new
DPI.
Also rescale m_requestedSashPosition if it's valid even if it's not
clear whether this can happen or not.
This was broken since f24b3d5483 (Save last wxSplitterWindow position
before it was unsplit, 2024-02-12) which accidentally used the wrong
lastSplitPos component when restoring.
Just use {Save,Restore}Coord() to restore the columns widths instead of
{Save,Restore}Value() to rescale the saved values if necessary.
Add a unit test checking that this works as expected.
Make the code creating a wxDVC and saving it available in a reusable
function to allow calling it from another place in the upcoming commit.
No real changes, this is a pure refactoring.
Add support at wxPersistentWindow level for saving the DPI at which the
window coordinates were saved to allow rescaling the values by the ratio
of this DPI to the current one if the DPI has changed between saving and
restoring.
This allows keeping the same proportional size of the window after DPI
change on the platforms not using DPI-independent pixels (such as wxMSW)
too by just using the new {Save,Restore}Coord() functions instead of
{Save,Restore}Value() for any quantities that need to be scaled.
Do this for wxPersistentTLW to update the window size to remain
proportionally the same after DPI change.