/
window.go
2249 lines (2040 loc) · 72.9 KB
/
window.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright (c) 2023 The Go-Curses Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ctk
import (
_ "embed"
"fmt"
"github.com/go-curses/cdk"
cenums "github.com/go-curses/cdk/lib/enums"
"github.com/go-curses/cdk/lib/paint"
"github.com/go-curses/cdk/lib/ptypes"
"github.com/go-curses/cdk/lib/sync"
"github.com/go-curses/cdk/memphis"
"github.com/go-curses/ctk/lib/enums"
)
const TypeWindow cdk.CTypeTag = "ctk-window"
func init() {
_ = cdk.TypesManager.AddType(TypeWindow, func() interface{} { return MakeWindow() })
ctkBuilderTranslators[TypeWindow] = func(builder Builder, widget Widget, name, value string) error {
switch name {
case "transient_for", "transient-for":
if tfw := builder.GetWidget(value); tfw != nil {
if err := widget.SetStructProperty(PropertyTransientFor, tfw); err != nil {
return err
}
return nil
} else {
builder.LogError("failed to set transient-for, unknown widget id/name: %v", value)
}
}
return ErrFallthrough
}
}
//go:embed ctk.default.styles
var DefaultStyles string
// Window Hierarchy:
//
// Object
// +- Widget
// +- Container
// +- Bin
// +- Window
// +- Dialog
// +- Assistant
// +- OffscreenWindow
// +- Plug
//
// In the Curses Tool Kit, the Window type is an extension of the CTK Bin
// type and also implements the cdk.Window interface so that it can be utilized
// within the Curses Development Kit framework. A Window is a TOPLEVEL Widget
// that can contain other widgets.
type Window interface {
cdk.Window
Bin
ImportStylesFromString(css string) (err error)
ReplaceStylesFromString(css string) (err error)
ExportStylesToString() (css string)
ApplyStylesTo(widget Widget)
ReApplyStyles()
SetTitle(title string)
SetResizable(resizable bool)
GetResizable() (value bool)
AddAccelGroup(accelGroup AccelGroup)
RemoveAccelGroup(accelGroup AccelGroup)
ActivateFocus() (value bool)
ActivateDefault() (value bool)
SetModal(modal bool)
SetPosition(position enums.WindowPosition)
SetTransientFor(parent Window)
SetDestroyWithParent(setting bool)
IsActive() (active bool)
HasToplevelFocus() (focused bool)
ListTopLevels() (value []Window)
AddMnemonic(keyval rune, target Widget)
RemoveMnemonic(keyval rune, target Widget)
RemoveWidgetMnemonics(target Widget)
ActivateMnemonic(keyval rune, modifier cdk.ModMask) (activated bool)
ActivateKey(event cdk.EventKey) (value bool)
PropagateKeyEvent(event cdk.EventKey) (value bool)
GetFocus() (focus Widget)
SetFocus(focus Widget)
GetDefaultWidget() (value Widget)
SetDefault(defaultWidget Widget)
Present()
PresentWithTime(timestamp int)
Iconify()
Deiconify()
Stick()
Unstick()
Maximize()
Unmaximize()
Fullscreen()
Unfullscreen()
SetKeepAbove(setting bool)
SetKeepBelow(setting bool)
SetDecorated(setting bool)
SetDeletable(setting bool)
SetMnemonicModifier(modifier cdk.ModMask)
SetWindowType(hint cenums.WindowType)
SetTypeHint(hint enums.WindowTypeHint)
SetSkipTaskbarHint(setting bool)
SetSkipPagerHint(setting bool)
SetUrgencyHint(setting bool)
SetAcceptFocus(setting bool)
SetFocusOnMap(setting bool)
SetStartupId(startupId string)
SetRole(role string)
GetDecorated() (value bool)
GetDeletable() (value bool)
GetDefaultSize(width int, height int)
GetDestroyWithParent() (value bool)
GetMnemonicModifier() (value cdk.ModMask)
GetModal() (value bool)
GetPosition(rootX int, rootY int)
GetRole() (value string)
GetSize() (width, height int)
GetTitle() (value string)
GetTransientFor() (value Window)
GetWindowType() (value cenums.WindowType)
GetTypeHint() (value enums.WindowTypeHint)
GetSkipTaskbarHint() (value bool)
GetSkipPagerHint() (value bool)
GetUrgencyHint() (value bool)
GetAcceptFocus() (value bool)
GetFocusOnMap() (value bool)
HasGroup() (value bool)
Move(x int, y int)
ParseGeometry(geometry string) (value bool)
ReshowWithInitialSize()
SetAutoStartupNotification(setting bool)
GetOpacity() (value float64)
SetOpacity(opacity float64)
GetMnemonicsVisible() (value bool)
SetMnemonicsVisible(setting bool)
GetDisplay() (dm cdk.Display)
SetDisplay(dm cdk.Display)
RequestDrawAndShow()
RequestDrawAndSync()
GetVBox() (vbox VBox)
GetNextFocus() (next Widget)
GetPreviousFocus() (previous Widget)
FocusNext() cenums.EventFlag
FocusPrevious() cenums.EventFlag
GetEventFocus() (o cdk.Object)
SetEventFocus(o cdk.Object)
}
var _ Window = (*CWindow)(nil)
// The CWindow structure implements the Window interface and is exported to
// facilitate type embedding with custom implementations. No member variables
// are exported as the interface methods are the only intended means of
// interacting with Window objects.
type CWindow struct {
CBin
display cdk.Display
prevMouseEvent *cdk.EventMouse
eventFocus interface{}
hoverFocus Widget
hoverFocused *WidgetSlice
accelGroups AccelGroups
mnemonics []*mnemonicEntry
mnemonicMod cdk.ModMask
mnemonicLock *sync.RWMutex
receivingPaste bool
pasteBuffer *string
styleSheet *cStyleSheet
}
type mnemonicEntry struct {
key rune
target Widget
}
// MakeWindow is used by the Buildable system to construct a new Window.
func MakeWindow() Window {
return NewWindow()
}
// NewWindow is a constructor for new Window instances.
func NewWindow() (w Window) {
w = new(CWindow)
w.Init()
return
}
// NewWindowWithTitle is a constructor for new Window instances that also sets
// the Window title to the string given.
func NewWindowWithTitle(title string) (w Window) {
w = NewWindow()
w.SetTitle(title)
return
}
// Init initializes a Window object. This must be called at least once to
// set up the necessary defaults and allocate any memory structures. Calling
// this more than once is safe though unnecessary. Only the first call will
// result in any effect upon the Window instance. Init is used in the
// NewWindow constructor and only necessary when implementing a derivative
// Window type.
func (w *CWindow) Init() (already bool) {
if w.InitTypeItem(TypeWindow, w) {
return true
}
w.CBin.Init()
w.SetState(0)
w.flags = enums.NULL_WIDGET_FLAG
w.SetFlags(enums.TOPLEVEL | enums.SENSITIVE | enums.APP_PAINTABLE)
w.prevMouseEvent = cdk.NewEventMouse(0, 0, 0, 0)
w.parent = w
if d := cdk.GetDefaultDisplay(); d != nil {
w.display = d
} else {
w.display = nil
}
w.origin.X = 0
w.origin.Y = 0
w.accelGroups = NewAccelGroups()
w.mnemonics = make([]*mnemonicEntry, 0)
w.mnemonicMod = cdk.ModAlt
w.mnemonicLock = &sync.RWMutex{}
w.hoverFocus = nil
w.hoverFocused = new(WidgetSlice)
w.receivingPaste = false
w.pasteBuffer = nil
_ = w.InstallProperty(PropertyWindowType, cdk.StructProperty, true, cenums.WINDOW_TOPLEVEL)
_ = w.InstallProperty(PropertyAcceptFocus, cdk.BoolProperty, true, true)
_ = w.InstallProperty(PropertyDecorated, cdk.BoolProperty, true, true)
_ = w.InstallProperty(PropertyDefaultHeight, cdk.IntProperty, true, -1)
_ = w.InstallProperty(PropertyDefaultWidth, cdk.IntProperty, true, -1)
_ = w.InstallProperty(PropertyDeletable, cdk.BoolProperty, true, true)
_ = w.InstallProperty(PropertyDestroyWithParent, cdk.BoolProperty, true, false)
_ = w.InstallProperty(PropertyFocusOnMap, cdk.BoolProperty, true, true)
_ = w.InstallProperty(PropertyFocusedWidget, cdk.StructProperty, true, nil)
_ = w.InstallProperty(PropertyGravity, cdk.StructProperty, true, enums.GravityNorthWest)
_ = w.InstallProperty(PropertyHasToplevelFocus, cdk.BoolProperty, false, false)
_ = w.InstallProperty(PropertyIcon, cdk.StructProperty, true, nil)
_ = w.InstallProperty(PropertyIconName, cdk.StringProperty, true, "")
_ = w.InstallProperty(PropertyIsActive, cdk.BoolProperty, false, false)
_ = w.InstallProperty(PropertyMnemonicsVisible, cdk.BoolProperty, true, true)
_ = w.InstallProperty(PropertyModal, cdk.BoolProperty, true, false)
_ = w.InstallProperty(PropertyOpacity, cdk.FloatProperty, true, 1)
_ = w.InstallProperty(PropertyResizable, cdk.BoolProperty, true, true)
_ = w.InstallProperty(PropertyRole, cdk.StringProperty, true, "")
_ = w.InstallProperty(PropertyScreen, cdk.StructProperty, true, nil)
_ = w.InstallProperty(PropertySkipPagerHint, cdk.BoolProperty, true, false)
_ = w.InstallProperty(PropertySkipTaskbarHint, cdk.BoolProperty, true, false)
_ = w.InstallProperty(PropertyStartupId, cdk.StringProperty, true, "")
_ = w.InstallProperty(PropertyTitle, cdk.StringProperty, true, "")
_ = w.InstallProperty(PropertyTransientFor, cdk.StructProperty, true, nil)
_ = w.InstallProperty(PropertyTypeHint, cdk.StructProperty, true, enums.WindowTypeHintNormal)
_ = w.InstallProperty(PropertyUrgencyHint, cdk.BoolProperty, true, false)
_ = w.InstallProperty(PropertyWindowPosition, cdk.StructProperty, true, enums.WinPosNone)
var err error
if w.styleSheet, err = newStyleSheetFromString(DefaultStyles); err != nil {
w.LogErr(err)
} else {
w.styleSheet = newStyleSheet()
}
w.SetWindow(w) // after stylesheet setup
w.Connect(SignalCdkEvent, WindowEventHandle, w.event)
w.Connect(SignalResize, WindowResizeHandle, w.resize)
w.Connect(SignalDraw, WindowDrawHandle, w.draw)
if err := w.SetProperty(PropertyWindow, w); err != nil {
w.LogErr(err)
}
_ = w.GetVBox()
if w.display != nil {
w.display.Connect(cdk.SignalFocusedWindow, WindowDisplayFocusHandle, w.displayFocusedWindow)
}
return false
}
// Build provides customizations to the Buildable system for Window Widgets.
func (w *CWindow) Build(builder Builder, element *CBuilderElement) error {
w.Freeze()
defer w.Thaw()
if err := w.CBin.Build(builder, element); err != nil {
return err
}
if len(element.Children) > 0 {
contentBox := w.GetVBox()
for _, child := range element.Children {
if newChild := builder.Build(child); newChild != nil {
child.Instance = newChild
if newChildWidget, ok := newChild.(Widget); ok {
newChildWidget.Show()
// if len(child.Packing) > 0 {
expand, fill, padding, packType := builder.ParsePacking(child)
if packType == enums.PackStart {
contentBox.PackStart(newChildWidget, expand, fill, padding)
} else {
contentBox.PackEnd(newChildWidget, expand, fill, padding)
}
if newChildWidget.HasFlags(enums.HAS_FOCUS) {
newChildWidget.GrabFocus()
}
} else {
contentBox.LogError("new child object is not a Widget type: %v (%T)")
}
}
}
}
return nil
}
func (w *CWindow) ImportStylesFromString(css string) (err error) {
w.Lock()
if err = w.styleSheet.ParseString(css); err != nil {
w.LogErr(err)
}
w.Unlock()
return
}
func (w *CWindow) ReplaceStylesFromString(css string) (err error) {
w.Lock()
var ss *cStyleSheet
if ss, err = newStyleSheetFromString(DefaultStyles); err != nil {
w.LogErr(err)
} else {
w.styleSheet = ss
}
w.Unlock()
return
}
func (w *CWindow) ExportStylesToString() (css string) {
css = w.styleSheet.String()
return
}
func (w *CWindow) ApplyStylesTo(widget Widget) {
w.styleSheet.ApplyStylesTo(widget)
}
func (w *CWindow) ReApplyStyles() {
var recurse func(top Widget)
recurse = func(top Widget) {
w.styleSheet.ApplyStylesTo(top)
if container, ok := top.Self().(Container); ok {
for _, child := range container.GetChildren() {
recurse(child)
}
}
}
recurse(w)
}
func (w *CWindow) Show() {
w.CBin.Show()
w.GetVBox().Show()
if display := w.GetDisplay(); display != nil {
w.Map()
display.MapWindowWithRegion(w, w.GetRegion())
}
w.SetState(enums.StatePrelight)
w.InvalidateAllChildren()
}
func (w *CWindow) ShowAll() {
w.GetVBox().ShowAll()
w.Show()
}
func (w *CWindow) Hide() {
w.CBin.Hide()
if display := w.GetDisplay(); display != nil {
// w.Unmap()
display.UnmapWindow(w)
}
}
// SetTitle updates the title of the Window. The title of a window will be
// displayed in its title bar; on the X Window System, the title bar is rendered
// by the window manager, so exactly how the title appears to users may vary
// according to a user's exact configuration. The title should help a user
// distinguish this window from other windows they may have open. A good
// title might include the application name and current document filename,
// for example.
//
// Parameters:
//
// title text for the title of the window
func (w *CWindow) SetTitle(title string) {
if err := w.SetStringProperty(PropertyTitle, title); err != nil {
w.LogErr(err)
}
}
// SetResizable updates whether the user can resize a window. Windows are user
// resizable by default.
//
// Parameters:
//
// resizable TRUE if the user can resize this window
func (w *CWindow) SetResizable(resizable bool) {
if err := w.SetBoolProperty(PropertyResizable, resizable); err != nil {
w.LogErr(err)
}
}
// GetResizable returns the value set by SetResizable.
func (w *CWindow) GetResizable() (value bool) {
var err error
if value, err = w.GetBoolProperty(PropertyResizable); err != nil {
w.LogErr(err)
}
return
}
// AddAccelGroup associates accel_group with window, such that calling
// AccelGroupsActivate on the window will activate accelerators in
// accel_group.
//
// Parameters:
//
// accelGroup a AccelGroup
func (w *CWindow) AddAccelGroup(accelGroup AccelGroup) {
w.Lock()
w.accelGroups.AddAccelGroup(w, accelGroup)
w.Unlock()
}
// RemoveAccelGroup reverses the effects of AddAccelGroup.
//
// Parameters:
//
// accelGroup a AccelGroup
func (w *CWindow) RemoveAccelGroup(accelGroup AccelGroup) {
w.Lock()
w.accelGroups.RemoveAccelGroup(w, accelGroup)
w.Unlock()
}
// Activates the current focused widget within the window.
// Returns:
//
// TRUE if a widget got activated.
func (w *CWindow) ActivateFocus() (value bool) {
if focused := w.GetFocus(); focused != nil {
if activatable, ok := focused.Self().(Activatable); ok {
activatable.Activate()
return true
}
}
return
}
// Activates the default widget for the window, unless the current focused
// widget has been configured to receive the default action (see
// WidgetSetReceivesDefault), in which case the focused widget is
// activated.
// Returns:
//
// TRUE if a widget got activated.
func (w *CWindow) ActivateDefault() (value bool) {
return false
}
// Sets a window modal or non-modal. Modal windows prevent interaction with
// other windows in the same application. To keep modal dialogs on top of
// main application windows, use SetTransientFor to make the
// dialog transient for the parent; most window managers will then disallow
// lowering the dialog below the parent.
// Parameters:
//
// modal whether the window is modal
func (w *CWindow) SetModal(modal bool) {
if err := w.SetBoolProperty(PropertyModal, modal); err != nil {
w.LogErr(err)
}
}
// This function sets up hints about how a window can be resized by the user.
// You can set a minimum and maximum size; allowed resize increments (e.g.
// for xterm, you can only resize by the size of a character); aspect ratios;
// and more. See the Geometry struct.
// Parameters:
// geometryWidget widget the geometry hints will be applied to
// geometry struct containing geometry information
// geomMask mask indicating which struct fields should be paid attention to
// func (w *CWindow) SetGeometryHints(geometryWidget Widget, geometry Geometry, geomMask WindowHints) {}
// Window gravity defines the meaning of coordinates passed to
// Move. See Move and Gravity for more details.
// The default window gravity is GDK_GRAVITY_NORTH_WEST which will typically
// "do what you mean."
// Parameters:
// gravity window gravity
// func (w *CWindow) SetGravity(gravity Gravity) {
// if err := w.SetStructProperty(PropertyGravity, gravity); err != nil {
// w.LogErr(err)
// }
// }
// Gets the value set by SetGravity.
// Returns:
// window gravity.
// [transfer none]
// func (w *CWindow) GetGravity() (value Gravity) {
// var err error
// if value, err = w.GetStructProperty(PropertyGravity); err != nil {
// w.LogErr(err)
// }
// return
// }
// Sets a position constraint for this window. If the old or new constraint
// is GTK_WIN_POS_CENTER_ALWAYS, this will also cause the window to be
// repositioned to satisfy the new constraint.
// Parameters:
//
// position a position constraint.
func (w *CWindow) SetPosition(position enums.WindowPosition) {}
// Dialog windows should be set transient for the main application window
// they were spawned from. This allows window managers to e.g. keep the
// dialog on top of the main window, or center the dialog over the main
// window. DialogNewWithButtons and other convenience functions in
// CTK will sometimes call SetTransientFor on your behalf.
// Passing NULL for parent unsets the current transient window. On Windows,
// this function puts the child window on top of the parent, much as the
// window manager would have done on X.
// Parameters:
//
// parent parent window, or NULL.
func (w *CWindow) SetTransientFor(parent Window) {
if err := w.SetStructProperty(PropertyTransientFor, parent); err != nil {
w.LogErr(err)
}
}
// If setting is TRUE, then destroying the transient parent of window will
// also destroy window itself. This is useful for dialogs that shouldn't
// persist beyond the lifetime of the main window they're associated with,
// for example.
// Parameters:
//
// setting whether to destroy window
//
// with its transient parent
func (w *CWindow) SetDestroyWithParent(setting bool) {
if err := w.SetBoolProperty(PropertyDestroyWithParent, setting); err != nil {
w.LogErr(err)
}
}
// // Sets the Screen where the window is displayed; if the window is already
// // mapped, it will be unmapped, and then remapped on the new screen.
// // Parameters:
// // screen a Screen.
// func (w *CWindow) SetScreen(screen Screen) {
// if err := w.SetStructProperty(PropertyScreen, screen); err != nil {
// w.LogErr(err)
// }
// }
//
// // Returns the Screen associated with window .
// // Returns:
// // a Screen.
// // [transfer none]
// func (w *CWindow) GetScreen() (value Screen) {
// var err error
// if value, err = w.GetStructProperty(PropertyScreen); err != nil {
// w.LogErr(err)
// }
// return
// }
// Returns whether the window is part of the current active toplevel. (That
// is, the toplevel window receiving keystrokes.) The return value is TRUE if
// the window is active toplevel itself, but also if it is, say, a Plug
// embedded in the active toplevel. You might use this function if you wanted
// to draw a widget differently in an active window from a widget in an
// inactive window. See HasToplevelFocus
// Returns:
//
// TRUE if the window part of the current active window.
func (w *CWindow) IsActive() (active bool) {
if focused := w.display.FocusedWindow(); focused != nil {
if focused.ObjectID() == w.ObjectID() {
return true
}
}
return false
}
// Returns whether the input focus is within this Window. For real
// toplevel windows, this is identical to IsActive, but for
// embedded windows, like Plug, the results will differ.
// Returns:
//
// TRUE if the input focus is within this Window
func (w *CWindow) HasToplevelFocus() (focused bool) {
return
}
// Returns a list of all existing toplevel windows. The widgets in the list
// are not individually referenced. If you want to iterate through the list
// and perform actions involving callbacks that might destroy the widgets,
// you must call g_list_foreach (result, (GFunc)g_object_ref, NULL) first,
// and then unref all the widgets afterwards.
// Returns:
//
// list of toplevel widgets.
// [element-type Widget][transfer container]
func (w *CWindow) ListTopLevels() (value []Window) {
w.LogError("method unimplemented")
return []Window{w}
}
// Adds a mnemonic to this window.
// Parameters:
//
// keyval the mnemonic
// target the widget that gets activated by the mnemonic
func (w *CWindow) AddMnemonic(keyval rune, target Widget) {
w.mnemonicLock.Lock()
for _, entry := range w.mnemonics {
if entry.key == keyval {
if widget, ok := entry.target.Self().(Sensitive); ok {
if tw, ok := target.Self().(Sensitive); ok {
if widget.ObjectID() == tw.ObjectID() {
w.mnemonicLock.Unlock()
return
}
}
}
}
}
if _, ok := target.Self().(Sensitive); ok {
w.mnemonics = append(w.mnemonics, &mnemonicEntry{
key: keyval,
target: target,
})
} else {
w.LogError("target is not a Widget: %v (%T)", target, target)
}
w.mnemonicLock.Unlock()
}
// Removes a mnemonic from this window.
// Parameters:
//
// keyval the mnemonic
// target the widget that gets activated by the mnemonic
func (w *CWindow) RemoveMnemonic(keyval rune, target Widget) {
w.mnemonicLock.Lock()
if tw, ok := target.Self().(Sensitive); ok {
var mnemonics []*mnemonicEntry
for _, entry := range w.mnemonics {
if entry.key == keyval {
if widget, ok := entry.target.Self().(Sensitive); ok {
if widget.ObjectID() != tw.ObjectID() {
mnemonics = append(mnemonics, entry)
}
}
}
}
w.mnemonics = mnemonics
} else {
w.LogError("target is not a Widget: %v (%T)", target, target)
}
w.mnemonicLock.Unlock()
}
// Removes all mnemonics from this window for the target Widget.
// Parameters:
//
// target the widget that gets activated by the mnemonic
func (w *CWindow) RemoveWidgetMnemonics(target Widget) {
w.mnemonicLock.Lock()
if tw, ok := target.Self().(Widget); ok {
var mnemonics []*mnemonicEntry
for _, entry := range w.mnemonics {
if widget, ok := entry.target.Self().(Widget); ok {
if widget.ObjectID() != tw.ObjectID() {
mnemonics = append(mnemonics, entry)
}
}
}
w.mnemonics = mnemonics
} else {
w.LogError("target is not a Widget: %v (%T)", target, target)
}
w.mnemonicLock.Unlock()
}
// Activates the targets associated with the mnemonic.
// Parameters:
//
// keyval the mnemonic
// modifier the modifiers
// returns TRUE if the activation is done.
func (w *CWindow) ActivateMnemonic(keyval rune, modifier cdk.ModMask) (activated bool) {
if !GetDefaultSettings().GetEnableMnemonics() {
return false
}
w.mnemonicLock.Lock()
if modifier == w.mnemonicMod {
for _, entry := range w.mnemonics {
if entry.key == keyval {
if sa, ok := entry.target.Self().(Sensitive); ok && sa.IsSensitive() && sa.IsVisible() {
w.mnemonicLock.Unlock()
sa.GrabFocus()
sa.Activate()
return true
}
}
}
}
w.mnemonicLock.Unlock()
return
}
// Activates mnemonics and accelerators for this Window. This is normally
// called by the default ::key_press_event handler for toplevel windows,
// however in some cases it may be useful to call this directly when
// overriding the standard key handling for a toplevel window.
// Parameters:
//
// event a EventKey
//
// Returns:
//
// TRUE if a mnemonic or accelerator was found and activated.
func (w *CWindow) ActivateKey(event cdk.EventKey) (value bool) {
return false
}
// Propagate a key press or release event to the focus widget and up the
// focus container chain until a widget handles event . This is normally
// called by the default ::key_press_event and ::key_release_event handlers
// for toplevel windows, however in some cases it may be useful to call this
// directly when overriding the standard key handling for a toplevel window.
// Parameters:
//
// event a EventKey
//
// Returns:
//
// TRUE if a widget in the focus chain handled the event.
func (w *CWindow) PropagateKeyEvent(event cdk.EventKey) (value bool) {
return false
}
// Retrieves the current focused widget within the window. Note that this is
// the widget that would have the focus if the toplevel window focused; if
// the toplevel window is not focused then WidgetHasFocus (widget) will
// not be TRUE for the widget.
// Returns:
//
// the currently focused widget, or NULL if there is none.
// [transfer none]
func (w *CWindow) GetFocus() (focus Widget) {
var err error
var ok bool
var focusStruct interface{}
if focusStruct, err = w.GetStructProperty(PropertyFocusedWidget); err != nil {
w.LogErr(err)
} else if focus, ok = focusStruct.(Widget); !ok && focusStruct != nil {
w.LogError("value stored in %v property is not of Widget type: %v (%T)", PropertyFocusedWidget, focusStruct, focusStruct)
} else if ok {
return
}
fc, _ := w.GetFocusChain()
if len(fc) > 0 {
w.SetFocus(fc[0])
focus = fc[0]
}
return
}
// If focus is not the current focus widget, and is focusable, sets it as the
// focus widget for the window. If focus is NULL, unsets the focus widget for
// this window. To set the focus to a particular widget in the toplevel, it
// is usually more convenient to use WidgetGrabFocus instead of this
// function.
//
// Parameters:
//
// focus widget to be the new focus widget, or NULL to unset
func (w *CWindow) SetFocus(focus Widget) {
// if transient := w.GetTransientFor(); transient != nil && w.ObjectID() != transient.ObjectID() {
// transient.SetFocus(focus)
// return
// }
if focus == nil {
if err := w.SetStructProperty(PropertyFocusedWidget, nil); err != nil {
w.LogErr(err)
} else {
w.Emit(SignalFocusChanged, nil)
}
return
}
if sensitive, ok := focus.Self().(Sensitive); ok {
if sensitive.CanFocus() && sensitive.IsVisible() && sensitive.IsSensitive() {
if err := w.SetStructProperty(PropertyFocusedWidget, focus); err != nil {
w.LogErr(err)
} else {
w.Emit(SignalFocusChanged, w, focus)
}
} else {
w.LogError("cannot focus, not visible or not sensitive")
}
} else {
w.LogError("does not implement Sensitive interface: %T %v", focus, focus)
}
}
// Returns the default widget for window . See SetDefault for
// more details.
// Returns:
//
// the default widget, or NULL if there is none.
// [transfer none]
func (w *CWindow) GetDefaultWidget() (value Widget) {
return nil
}
// The default widget is the widget that's activated when the user presses
// Enter in a dialog (for example). This function sets or unsets the default
// widget for a Window about. When setting (rather than unsetting) the
// default widget it's generally easier to call WidgetGrabFocus on
// the widget. Before making a widget the default widget, you must set the
// GTK_CAN_DEFAULT flag on the widget you'd like to make the default using
// GTK_WIDGET_SET_FLAGS.
// Parameters:
//
// defaultWidget widget to be the default, or NULL to unset the
//
// default widget for the toplevel.
func (w *CWindow) SetDefault(defaultWidget Widget) {}
// Presents a window to the user. This may mean raising the window in the
// stacking order, deiconifying it, moving it to the current desktop, and/or
// giving it the keyboard focus, possibly dependent on the user's platform,
// window manager, and preferences. If window is hidden, this function calls
// WidgetShow as well. This function should be used when the user
// tries to open a window that's already open. Say for example the
// preferences dialog is currently open, and the user chooses Preferences
// from the menu a second time; use Present to move the
// already-open dialog where the user can see it. If you are calling this
// function in response to a user interaction, it is preferable to use
// PresentWithTime.
func (w *CWindow) Present() {}
// Presents a window to the user in response to a user interaction. If you
// need to present a window without a timestamp, use Present.
// See Present for details.
// Parameters:
//
// timestamp the timestamp of the user interaction (typically a
//
// button or key press event) which triggered this call
func (w *CWindow) PresentWithTime(timestamp int) {}
// Asks to iconify (i.e. minimize) the specified window . Note that you
// shouldn't assume the window is definitely iconified afterward, because
// other entities (e.g. the user or window manager) could deiconify it again,
// or there may not be a window manager in which case iconification isn't
// possible, etc. But normally the window will end up iconified. Just don't
// write code that crashes if not. It's permitted to call this function
// before showing a window, in which case the window will be iconified before
// it ever appears onscreen. You can track iconification via the
// "window-state-event" signal on Widget.
func (w *CWindow) Iconify() {}
// Asks to deiconify (i.e. unminimize) the specified window . Note that you
// shouldn't assume the window is definitely deiconified afterward, because
// other entities (e.g. the user or window manager) could iconify it again
// before your code which assumes deiconification gets to run. You can track
// iconification via the "window-state-event" signal on Widget.
func (w *CWindow) Deiconify() {}
// Asks to stick window , which means that it will appear on all user
// desktops. Note that you shouldn't assume the window is definitely stuck
// afterward, because other entities (e.g. the user or window manager) could
// unstick it again, and some window managers do not support sticking
// windows. But normally the window will end up stuck. Just don't write code
// that crashes if not. It's permitted to call this function before showing a
// window. You can track stickiness via the "window-state-event" signal on
// Widget.
func (w *CWindow) Stick() {}
// Asks to unstick window , which means that it will appear on only one of
// the user's desktops. Note that you shouldn't assume the window is
// definitely unstuck afterward, because other entities (e.g. the user or
// window manager) could stick it again. But normally the window will end up
// stuck. Just don't write code that crashes if not. You can track stickiness
// via the "window-state-event" signal on Widget.
func (w *CWindow) Unstick() {}
// Asks to maximize window , so that it becomes full-screen. Note that you
// shouldn't assume the window is definitely maximized afterward, because
// other entities (e.g. the user or window manager) could unmaximize it
// again, and not all window managers support maximization. But normally the
// window will end up maximized. Just don't write code that crashes if not.
// It's permitted to call this function before showing a window, in which
// case the window will be maximized when it appears onscreen initially. You
// can track maximization via the "window-state-event" signal on Widget.
func (w *CWindow) Maximize() {}
// Asks to unmaximize window . Note that you shouldn't assume the window is
// definitely unmaximized afterward, because other entities (e.g. the user or
// window manager) could maximize it again, and not all window managers honor
// requests to unmaximize. But normally the window will end up unmaximized.
// Just don't write code that crashes if not. You can track maximization via
// the "window-state-event" signal on Widget.
func (w *CWindow) Unmaximize() {}
// Asks to place window in the fullscreen state. Note that you shouldn't
// assume the window is definitely full screen afterward, because other
// entities (e.g. the user or window manager) could unfullscreen it again,
// and not all window managers honor requests to fullscreen windows. But
// normally the window will end up fullscreen. Just don't write code that
// crashes if not. You can track the fullscreen state via the
// "window-state-event" signal on Widget.
func (w *CWindow) Fullscreen() {}
// Asks to toggle off the fullscreen state for window . Note that you
// shouldn't assume the window is definitely not full screen afterward,
// because other entities (e.g. the user or window manager) could fullscreen
// it again, and not all window managers honor requests to unfullscreen
// windows. But normally the window will end up restored to its normal state.
// Just don't write code that crashes if not. You can track the fullscreen
// state via the "window-state-event" signal on Widget.
func (w *CWindow) Unfullscreen() {}
// Asks to keep window above, so that it stays on top. Note that you
// shouldn't assume the window is definitely above afterward, because other
// entities (e.g. the user or window manager) could not keep it above, and
// not all window managers support keeping windows above. But normally the
// window will end kept above. Just don't write code that crashes if not.
// It's permitted to call this function before showing a window, in which
// case the window will be kept above when it appears onscreen initially. You
// can track the above state via the "window-state-event" signal on
// Widget. Note that, according to the Extended Window Manager Hints
// specification, the above state is mainly meant for user preferences and
// should not be used by applications e.g. for drawing attention to their
// dialogs.
// Parameters:
//
// setting whether to keep window
//
// above other windows
func (w *CWindow) SetKeepAbove(setting bool) {}
// Asks to keep window below, so that it stays in bottom. Note that you
// shouldn't assume the window is definitely below afterward, because other
// entities (e.g. the user or window manager) could not keep it below, and
// not all window managers support putting windows below. But normally the
// window will be kept below. Just don't write code that crashes if not. It's
// permitted to call this function before showing a window, in which case the
// window will be kept below when it appears onscreen initially. You can
// track the below state via the "window-state-event" signal on Widget.
// Note that, according to the Extended Window Manager Hints specification,
// the above state is mainly meant for user preferences and should not be
// used by applications e.g. for drawing attention to their dialogs.
// Parameters:
//
// setting whether to keep window
//
// below other windows
func (w *CWindow) SetKeepBelow(setting bool) {}
// Starts resizing a window. This function is used if an application has
// window resizing controls. When GDK can support it, the resize will be done
// using the standard mechanism for the window manager or windowing system.