KiCad PCB EDA Suite
Loading...
Searching...
No Matches
gtk/ui.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 Ian McInerney <Ian.S.McInerney at ieee.org>
5 * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <kiplatform/ui.h>
22
23#include <wx/choice.h>
24#include <wx/nonownedwnd.h>
25#include <wx/settings.h>
26#include <wx/window.h>
27#include <wx/log.h>
28
29#include <gtk/gtk.h>
30#include <gdk/gdk.h>
31
32#ifdef GDK_WINDOWING_X11
33#include <gdk/gdkx.h>
34#endif
35
36#ifdef GDK_WINDOWING_WAYLAND
37#include <gdk/gdkwayland.h>
38#endif
39
40#ifdef KICAD_WAYLAND
42#endif
43
44// Set WXTRACE=KICAD_WAYLAND to see logs
45const wxString traceWayland = wxS( "KICAD_WAYLAND" );
46
47
49{
50 wxColour bg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
51
52 // Weighted W3C formula
53 double brightness = ( bg.Red() / 255.0 ) * 0.299 +
54 ( bg.Green() / 255.0 ) * 0.587 +
55 ( bg.Blue() / 255.0 ) * 0.117;
56
57 return brightness < 0.5;
58}
59
60
62{
63 return wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
64}
65
66
67void KIPLATFORM::UI::ForceFocus( wxWindow* aWindow )
68{
69 aWindow->SetFocus();
70}
71
72
73bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow )
74{
75 if( !aWindow )
76 return false;
77
78 GtkWindow* window = GTK_WINDOW( aWindow->GetHandle() );
79
80 if( window )
81 return gtk_window_is_active( window );
82
83 // We shouldn't really ever reach this point
84 return false;
85}
86
87
88void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow )
89{
90 // Not needed on this platform
91}
92
93
95{
96 // Not needed on this platform
97}
98
99
100bool KIPLATFORM::UI::IsStockCursorOk( wxStockCursor aCursor )
101{
102 switch( aCursor )
103 {
104 case wxCURSOR_BULLSEYE:
105 case wxCURSOR_HAND:
106 case wxCURSOR_ARROW:
107 case wxCURSOR_BLANK:
108 return true;
109 default:
110 return false;
111 }
112}
113
114
123static void disable_area_apply_attributes_cb( GtkWidget* pItem, gpointer userdata )
124{
125 // GTK needs this enormous chain to get the actual type of item that we want
126 GtkMenuItem* pMenuItem = GTK_MENU_ITEM( pItem );
127 GtkWidget* child = gtk_bin_get_child( GTK_BIN( pMenuItem ) );
128 GtkCellView* pCellView = GTK_CELL_VIEW( child );
129 GtkCellLayout* pCellLayout = GTK_CELL_LAYOUT( pCellView );
130 GtkCellArea* pCellArea = gtk_cell_layout_get_area( pCellLayout );
131
132 g_signal_handlers_block_matched( pCellArea, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, userdata );
133}
134
135
136void KIPLATFORM::UI::LargeChoiceBoxHack( wxChoice* aChoice )
137{
138 AtkObject* atkObj = gtk_combo_box_get_popup_accessible( GTK_COMBO_BOX( aChoice->m_widget ) );
139
140 if( !atkObj || !GTK_IS_ACCESSIBLE( atkObj ) )
141 return;
142
143 GtkWidget* widget = gtk_accessible_get_widget( GTK_ACCESSIBLE( atkObj ) );
144
145 if( !widget || !GTK_IS_MENU( widget ) )
146 return;
147
148 GtkMenu* menu = GTK_MENU( widget );
149
150 gtk_container_foreach( GTK_CONTAINER( menu ), disable_area_apply_attributes_cb, menu );
151}
152
153
154void KIPLATFORM::UI::EllipsizeChoiceBox( wxChoice* aChoice )
155{
156 // This function is based on the code inside the function post_process_ui in
157 // gtkfilechooserwidget.c
158 GList* cells = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( aChoice->m_widget ) );
159
160 if( !cells )
161 return;
162
163 GtkCellRenderer* cell = (GtkCellRenderer*) cells->data;
164
165 if( !cell )
166 return;
167
168 g_object_set( G_OBJECT( cell ), "ellipsize", PANGO_ELLIPSIZE_END, nullptr );
169
170 // Only the list of cells must be freed, the renderer isn't ours to free
171 g_list_free( cells );
172}
173
174
175double KIPLATFORM::UI::GetPixelScaleFactor( const wxWindow* aWindow )
176{
177 double val = 1.0;
178
179 GtkWidget* widget = static_cast<GtkWidget*>( aWindow->GetHandle() );
180
181 if( widget && gtk_check_version( 3, 10, 0 ) == nullptr )
182 val = gtk_widget_get_scale_factor( widget );
183
184 return val;
185}
186
187
188double KIPLATFORM::UI::GetContentScaleFactor( const wxWindow* aWindow )
189{
190 // TODO: Do we need something different here?
191 return GetPixelScaleFactor( aWindow );
192}
193
194
195wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow )
196{
197 return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),
198 aWindow->GetSize().GetY() - wxSystemSettings::GetMetric( wxSYS_HSCROLL_Y ) );
199}
200
201
202void KIPLATFORM::UI::SetOverlayScrolling( const wxWindow* aWindow, bool overlay )
203{
204 gtk_scrolled_window_set_overlay_scrolling( GTK_SCROLLED_WINDOW( aWindow->GetHandle() ),
205 overlay );
206}
207
208
210{
211 gboolean allowed = 1;
212
213 g_object_get( gtk_settings_get_default(), "gtk-menu-images", &allowed, NULL );
214
215 return !!allowed;
216}
217
218
219#if defined( GDK_WINDOWING_WAYLAND ) && defined( KICAD_WAYLAND )
220
221static bool wayland_warp_pointer( GtkWidget* aWidget, GdkDisplay* aDisplay, GdkWindow* aWindow,
222 GdkDevice* aPtrDev, int aX, int aY );
223
224// GDK doesn't know if we've moved the cursor using Wayland pointer constraints.
225// So emulate the actual position here
226static wxPoint s_warped_from;
227static wxPoint s_warped_to;
228
230{
231 wxPoint wx_pos = wxGetMousePosition();
232
233 if( wx_pos == s_warped_from )
234 {
235 wxLogTrace( traceWayland, wxS( "Faked mouse pos %d %d -> %d %d" ), wx_pos.x, wx_pos.y,
236 s_warped_to.x, s_warped_to.y );
237
238 return s_warped_to;
239 }
240 else
241 {
242 // Mouse has moved
243 s_warped_from = wxPoint();
244 s_warped_to = wxPoint();
245 }
246
247 return wx_pos;
248}
249
250#endif
251
252
253void KIPLATFORM::UI::WarpPointer( wxWindow* aWindow, int aX, int aY )
254{
255 if( !wxGetEnv( wxT( "WAYLAND_DISPLAY" ), nullptr ) )
256 {
257 aWindow->WarpPointer( aX, aY );
258 }
259 else
260 {
261 GtkWidget* widget = static_cast<GtkWidget*>( aWindow->GetHandle() );
262
263 GdkDisplay* disp = gtk_widget_get_display( widget );
264 GdkSeat* seat = gdk_display_get_default_seat( disp );
265 GdkDevice* ptrdev = gdk_seat_get_pointer( seat );
266
267#if defined( GDK_WINDOWING_WAYLAND ) && defined( KICAD_WAYLAND )
268 if( GDK_IS_WAYLAND_DISPLAY( disp ) )
269 {
270 wxPoint initialPos = wxGetMousePosition();
271 GdkWindow* win = aWindow->GTKGetDrawingWindow();
272
273 if( wayland_warp_pointer( widget, disp, win, ptrdev, aX, aY ) )
274 {
275 s_warped_from = initialPos;
276 s_warped_to = aWindow->ClientToScreen( wxPoint( aX, aY ) );
277
278 wxLogTrace( traceWayland, wxS( "Set warped from %d %d to %d %d" ), s_warped_from.x,
279 s_warped_from.y, s_warped_to.x, s_warped_to.y );
280 }
281 }
282#endif
283#ifdef GDK_WINDOWING_X11
284 if( GDK_IS_X11_DISPLAY( disp ) )
285 {
286 GdkWindow* win = gdk_device_get_window_at_position( ptrdev, nullptr, nullptr );
287 GdkCursor* blank_cursor = gdk_cursor_new_for_display( disp, GDK_BLANK_CURSOR );
288 GdkCursor* cur_cursor = gdk_window_get_cursor( win );
289
290 if( cur_cursor )
291 g_object_ref( cur_cursor );
292
293 gdk_window_set_cursor( win, blank_cursor );
294 aWindow->WarpPointer( aX, aY );
295 gdk_window_set_cursor( win, cur_cursor );
296 }
297#endif
298 }
299}
300
301
302void KIPLATFORM::UI::ImmControl( wxWindow* aWindow, bool aEnable )
303{
304}
305
306//
307// **** Wayland hacks ahead ****
308//
309
310#if defined( GDK_WINDOWING_WAYLAND ) && defined( KICAD_WAYLAND )
311
312static bool s_wl_initialized = false;
313static struct wl_compositor* s_wl_compositor = NULL;
314static struct zwp_pointer_constraints_v1* s_wl_pointer_constraints = NULL;
315static struct zwp_confined_pointer_v1* s_wl_confined_pointer = NULL;
316static struct wl_region* s_wl_confinement_region = NULL;
317static bool s_wl_locked_flag = false;
318
319static void handle_global( void* data, struct wl_registry* registry, uint32_t name,
320 const char* interface, uint32_t version )
321{
322 if( strcmp( interface, wl_compositor_interface.name ) == 0 )
323 {
324 wxLogTrace( traceWayland, "handle_global received %s", interface );
325
326 s_wl_compositor = static_cast<wl_compositor*>(
327 wl_registry_bind( registry, name, &wl_compositor_interface, version ) );
328 }
329 else if( strcmp( interface, zwp_pointer_constraints_v1_interface.name ) == 0 )
330 {
331 wxLogTrace( traceWayland, "handle_global received %s", interface );
332
333 s_wl_pointer_constraints = static_cast<zwp_pointer_constraints_v1*>( wl_registry_bind(
334 registry, name, &zwp_pointer_constraints_v1_interface, version ) );
335 }
336}
337
338static const struct wl_registry_listener registry_listener = {
339 .global = handle_global,
340 .global_remove = NULL,
341};
342
343static void confined_handler( void* data, struct zwp_confined_pointer_v1* zwp_confined_pointer_v1 )
344{
345 wxLogTrace( traceWayland, wxS( "Pointer confined" ) );
346}
347
348static void unconfined_handler( void* data,
349 struct zwp_confined_pointer_v1* zwp_confined_pointer_v1 )
350{
351 wxLogTrace( traceWayland, wxS( "Pointer unconfined" ) );
352}
353
354static const struct zwp_confined_pointer_v1_listener confined_pointer_listener = {
355 .confined = confined_handler,
356 .unconfined = unconfined_handler
357};
358
359static void locked_handler( void* data, struct zwp_locked_pointer_v1* zwp_locked_pointer_v1 )
360{
361 s_wl_locked_flag = true;
362 wxLogTrace( traceWayland, wxS( "Pointer locked" ) );
363}
364
365static void unlocked_handler( void* data, struct zwp_locked_pointer_v1* zwp_locked_pointer_v1 )
366{
367 wxLogTrace( traceWayland, wxS( "Pointer unlocked" ) );
368}
369
370static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
371 .locked = locked_handler,
372 .unlocked = unlocked_handler
373};
374
375
379static void initialize_wayland( wl_display* wldisp )
380{
381 if( s_wl_initialized )
382 {
383 return;
384 }
385
386 struct wl_registry* registry = wl_display_get_registry( wldisp );
387 wl_registry_add_listener( registry, &registry_listener, NULL );
388 wl_display_roundtrip( wldisp );
389 s_wl_initialized = true;
390}
391
392
393struct zwp_locked_pointer_v1* s_wl_locked_pointer = NULL;
394
395static int s_after_paint_handler_id = 0;
396
397static void on_frame_clock_after_paint( GdkFrameClock* clock, GtkWidget* widget )
398{
399 if( s_wl_locked_pointer )
400 {
401 zwp_locked_pointer_v1_destroy( s_wl_locked_pointer );
402 s_wl_locked_pointer = NULL;
403
404 wxLogTrace( traceWayland, wxS( "after-paint: locked_pointer destroyed" ) );
405
406 g_signal_handler_disconnect( (gpointer) clock, s_after_paint_handler_id );
407 s_after_paint_handler_id = 0;
408
409 // restore confinement
410 if( s_wl_confinement_region != NULL )
411 {
412 wxLogTrace( traceWayland, wxS( "after-paint: Restoring confinement" ) );
413
414 GdkDisplay* disp = gtk_widget_get_display( widget );
415 GdkSeat* seat = gdk_display_get_default_seat( disp );
416 GdkDevice* ptrdev = gdk_seat_get_pointer( seat );
417 GdkWindow* window = gtk_widget_get_window( widget );
418
419 wl_display* wldisp = gdk_wayland_display_get_wl_display( disp );
420 wl_surface* wlsurf = gdk_wayland_window_get_wl_surface( window );
421 wl_pointer* wlptr = gdk_wayland_device_get_wl_pointer( ptrdev );
422
423 s_wl_confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
424 s_wl_pointer_constraints, wlsurf, wlptr, s_wl_confinement_region,
426
427 wl_display_roundtrip( wldisp );
428 }
429 }
430}
431
432
433static bool wayland_warp_pointer( GtkWidget* aWidget, GdkDisplay* aDisplay, GdkWindow* aWindow,
434 GdkDevice* aPtrDev, int aX, int aY )
435{
436 wl_display* wldisp = gdk_wayland_display_get_wl_display( aDisplay );
437 wl_surface* wlsurf = gdk_wayland_window_get_wl_surface( aWindow );
438 wl_pointer* wlptr = gdk_wayland_device_get_wl_pointer( aPtrDev );
439
440 if( s_after_paint_handler_id )
441 {
442 // Previous paint not done yet
443 wxLogTrace( traceWayland, wxS( "Not warping: after-paint pending" ) );
444 return false;
445 }
446
447 initialize_wayland( wldisp );
448
449 if( s_wl_locked_pointer )
450 {
451 // This shouldn't happen but let's be safe
452 wxLogTrace( traceWayland, wxS( "** Destroying previous locked_pointer **" ) );
453 zwp_locked_pointer_v1_destroy( s_wl_locked_pointer );
454 wl_display_roundtrip( wldisp );
455 s_wl_locked_pointer = NULL;
456 }
457
458 // wl_surface_commit causes an assert on GNOME, but has to be called on KDE
459 // before destroying the locked pointer, so wait until GDK commits the surface.
460 GdkFrameClock* frame_clock = gdk_window_get_frame_clock( aWindow );
461 s_after_paint_handler_id = g_signal_connect_after(
462 frame_clock, "after-paint", G_CALLBACK( on_frame_clock_after_paint ), aWidget );
463
464 // temporary disable confinement to allow pointer warping
465 if( s_wl_confinement_region && s_wl_confined_pointer )
466 {
467 zwp_confined_pointer_v1_destroy( s_wl_confined_pointer );
468 wl_display_roundtrip( wldisp );
469 s_wl_confined_pointer = NULL;
470 }
471
472 s_wl_locked_flag = false;
473
474 s_wl_locked_pointer =
475 zwp_pointer_constraints_v1_lock_pointer( s_wl_pointer_constraints, wlsurf, wlptr, NULL,
477
478 zwp_locked_pointer_v1_add_listener(s_wl_locked_pointer, &locked_pointer_listener, NULL);
479
480 gint wx, wy;
481 gtk_widget_translate_coordinates( aWidget, gtk_widget_get_toplevel( aWidget ), 0, 0, &wx, &wy );
482
483 zwp_locked_pointer_v1_set_cursor_position_hint( s_wl_locked_pointer, wl_fixed_from_int( aX + wx ),
484 wl_fixed_from_int( aY + wy ) );
485
486 // Don't call wl_surface_commit, wait for GDK because of an assert on GNOME.
487 wl_display_roundtrip( wldisp ); // To receive "locked" event
488
489 return s_wl_locked_flag;
490}
491
492
493void KIPLATFORM::UI::InfiniteDragPrepareWindow( wxWindow* aWindow )
494{
495 wxLogTrace( traceWayland, wxS( "InfiniteDragPrepareWindow" ) );
496
497 if( s_wl_confined_pointer != NULL )
498 {
500 }
501
502 GtkWidget* widget = static_cast<GtkWidget*>( aWindow->GetHandle() );
503 GdkDisplay* disp = gtk_widget_get_display( widget );
504
505 if( !GDK_IS_WAYLAND_DISPLAY( disp ) )
506 {
507 return;
508 }
509
510 GdkSeat* seat = gdk_display_get_default_seat( disp );
511 GdkDevice* ptrdev = gdk_seat_get_pointer( seat );
512 GdkWindow* win = aWindow->GTKGetDrawingWindow();
513
514 wl_display* wldisp = gdk_wayland_display_get_wl_display( disp );
515 wl_surface* wlsurf = gdk_wayland_window_get_wl_surface( win );
516 wl_pointer* wlptr = gdk_wayland_device_get_wl_pointer( ptrdev );
517
518 initialize_wayland( wldisp );
519
520 gint x, y, width, height;
521 gdk_window_get_geometry( gdk_window_get_toplevel( win ), &x, &y, &width, &height );
522
523 wxLogTrace( traceWayland, wxS( "Confine region: %d %d %d %d" ), x, y, width, height );
524
525 s_wl_confinement_region = wl_compositor_create_region( s_wl_compositor );
526 wl_region_add( s_wl_confinement_region, x, y, width, height );
527
528 s_wl_confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
529 s_wl_pointer_constraints, wlsurf, wlptr, s_wl_confinement_region,
531
532 zwp_confined_pointer_v1_add_listener(s_wl_confined_pointer, &confined_pointer_listener, NULL);
533
534 wl_display_roundtrip( wldisp );
535};
536
537
539{
540 wxLogTrace( traceWayland, wxS( "InfiniteDragReleaseWindow" ) );
541
542 if( s_wl_confined_pointer )
543 {
544 zwp_confined_pointer_v1_destroy( s_wl_confined_pointer );
545 s_wl_confined_pointer = NULL;
546 }
547
548 if( s_wl_confinement_region )
549 {
550 wl_region_destroy( s_wl_confinement_region );
551 s_wl_confinement_region = NULL;
552 }
553};
554
555
556#else // No Wayland support
557
558
560{
561 // Not needed on X11
562};
563
564
566{
567 // Not needed on X11
568};
569
570
572{
573 return wxGetMousePosition();
574}
575
576
577#endif
const char * name
Definition: DXF_plotter.cpp:57
static void zwp_confined_pointer_v1_destroy(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
Destroy the confined pointer object.
static int zwp_confined_pointer_v1_add_listener(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, const struct zwp_confined_pointer_v1_listener *listener, void *data)
static void zwp_locked_pointer_v1_set_cursor_position_hint(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, wl_fixed_t surface_x, wl_fixed_t surface_y)
Set the cursor position hint relative to the top left corner of the surface.
static int zwp_locked_pointer_v1_add_listener(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, const struct zwp_locked_pointer_v1_listener *listener, void *data)
static void zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
Destroy the locked pointer object.
static struct zwp_locked_pointer_v1 * zwp_pointer_constraints_v1_lock_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
The lock_pointer request lets the client request to disable movements of the virtual pointer (i....
static struct zwp_confined_pointer_v1 * zwp_pointer_constraints_v1_confine_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
The confine_pointer request lets the client request to confine the pointer cursor to a given region.
@ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT
the pointer constraint is defunct once deactivated
static void disable_area_apply_attributes_cb(GtkWidget *pItem, gpointer userdata)
The following two functions are based on the "hack" contained in the attached patch at https://gitlab...
Definition: gtk/ui.cpp:123
const wxString traceWayland
Definition: gtk/ui.cpp:45
bool AllowIconsInMenus()
If the user has disabled icons system-wide, we check that here.
Definition: gtk/ui.cpp:209
void EllipsizeChoiceBox(wxChoice *aChoice)
Configure a wxChoice control to ellipsize the shown text in the button with the ellipses placed at th...
Definition: gtk/ui.cpp:154
void FixupCancelButtonCmdKeyCollision(wxWindow *aWindow)
Definition: gtk/ui.cpp:94
void SetOverlayScrolling(const wxWindow *aWindow, bool overlay)
Used to set overlay/non-overlay scrolling mode in a window.
Definition: gtk/ui.cpp:202
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition: gtk/ui.cpp:571
void ImmControl(wxWindow *aWindow, bool aEnable)
Configures the IME mode of a given control handle.
Definition: gtk/ui.cpp:302
double GetPixelScaleFactor(const wxWindow *aWindow)
Tries to determine the pixel scaling factor currently in use for the window.
Definition: gtk/ui.cpp:175
void InfiniteDragReleaseWindow()
On Wayland, allows the cursor to freely move again after a drag (see InfiniteDragPrepareWindow).
Definition: gtk/ui.cpp:565
bool IsStockCursorOk(wxStockCursor aCursor)
Checks if we designated a stock cursor for this OS as "OK" or else we may need to load a custom one.
Definition: gtk/ui.cpp:100
double GetContentScaleFactor(const wxWindow *aWindow)
Tries to determine the content scaling factor currently in use for the window.
Definition: gtk/ui.cpp:188
void InfiniteDragPrepareWindow(wxWindow *aWindow)
On Wayland, restricts the pointer movement to a rectangle slightly bigger than the given wxWindow.
Definition: gtk/ui.cpp:559
void WarpPointer(wxWindow *aWindow, int aX, int aY)
Move the mouse cursor to a specific position relative to the window.
Definition: gtk/ui.cpp:253
void LargeChoiceBoxHack(wxChoice *aChoice)
Configure a wxChoice control to support a lot of entries by disabling functionality that makes adding...
Definition: gtk/ui.cpp:136
void ReparentQuasiModal(wxNonOwnedWindow *aWindow)
Move a window's parent to be the top-level window and force the window to be on top.
Definition: gtk/ui.cpp:88
wxColour GetDialogBGColour()
Definition: gtk/ui.cpp:61
bool IsWindowActive(wxWindow *aWindow)
Check to see if the given window is the currently active window (e.g.
Definition: gtk/ui.cpp:73
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: gtk/ui.cpp:195
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:67
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition: gtk/ui.cpp:48
std::shared_ptr< PNS_LOG_VIEWER_OVERLAY > overlay
Definition: playground.cpp:36
void(* confined)(void *data, struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
pointer confined
void(* locked)(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
lock activation event
const struct wl_interface zwp_pointer_constraints_v1_interface