From 2d755f609dc9a1ee8f8de361c3edd76a210be698 Mon Sep 17 00:00:00 2001 From: piotr Date: Wed, 27 Nov 2024 03:05:46 +0100 Subject: [PATCH] migrate to diamondburned GTK bindings --- go.mod | 14 ++-- go.sum | 25 +++--- main.go | 191 ++++++++++++++++++++---------------------- tools.go | 65 +++++++-------- uicomponents.go | 218 ++++++++++++++++++++++-------------------------- 5 files changed, 244 insertions(+), 269 deletions(-) diff --git a/go.mod b/go.mod index 4aa65c9..a2fc0b3 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,19 @@ go 1.23 require ( github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 - github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774 - github.com/fsnotify/fsnotify v1.7.0 - github.com/gotk3/gotk3 v0.6.5-0.20240618185848-ff349ae13f56 + github.com/diamondburned/gotk4-layer-shell/pkg v0.0.0-20240109211357-6efa9f6dc438 + github.com/diamondburned/gotk4/pkg v0.3.1 + github.com/expr-lang/expr v1.16.9 + github.com/fsnotify/fsnotify v1.8.0 github.com/joshuarubin/go-sway v1.2.0 github.com/sirupsen/logrus v1.9.3 ) require ( - github.com/expr-lang/expr v1.16.9 // indirect + github.com/KarpelesLab/weak v0.1.1 // indirect github.com/joshuarubin/lifecycle v1.1.4 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect + go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect ) diff --git a/go.sum b/go.sum index 7c87659..62d795b 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,20 @@ +github.com/KarpelesLab/weak v0.1.1 h1:fNnlPo3aypS9tBzoEQluY13XyUfd/eWaSE/vMvo9s4g= +github.com/KarpelesLab/weak v0.1.1/go.mod h1:pzXsWs5f2bf+fpgHayTlBE1qJpO3MpJKo5sRaLu1XNw= github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 h1:28uU3TtuvQ6KRndxg9TrC868jBWmSKgh0GTXkACCXmA= github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37/go.mod h1:6AXRstqK+32jeFmw89QGL2748+dj34Av4xc/I9oo9BY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774 h1:o87OVL4olQBlVwN3+NSVQpS6gj9FWUYtxOfHXWZigUE= -github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774/go.mod h1:JHLx2Wz4mAPVwn4PFhC69ydwyHP4A3wQvlg7HKVVc1U= +github.com/diamondburned/gotk4-layer-shell/pkg v0.0.0-20240109211357-6efa9f6dc438 h1:Ymnl4B+Fn4srLxXbRV2RY1iHT2SH3oAkOfxeEeMI3Fg= +github.com/diamondburned/gotk4-layer-shell/pkg v0.0.0-20240109211357-6efa9f6dc438/go.mod h1:AjrxxF6teeNWgaEg0zIUwoqFtXlVTHlEGZvrOn7RXaQ= +github.com/diamondburned/gotk4/pkg v0.3.1 h1:uhkXSUPUsCyz3yujdvl7DSN8jiLS2BgNTQE95hk6ygg= +github.com/diamondburned/gotk4/pkg v0.3.1/go.mod h1:DqeOW+MxSZFg9OO+esk4JgQk0TiUJJUBfMltKhG+ub4= github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI= github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gotk3/gotk3 v0.6.1/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= -github.com/gotk3/gotk3 v0.6.5-0.20240618185848-ff349ae13f56 h1:eR+xxC8qqKuPMTucZqaklBxLIT7/4L7dzhlwKMrDbj8= -github.com/gotk3/gotk3 v0.6.5-0.20240618185848-ff349ae13f56/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/joshuarubin/go-sway v1.2.0 h1:t3eqW504//uj9PDwFf0+IVfkD+WoOGaDX5gYIe0BHyM= github.com/joshuarubin/go-sway v1.2.0/go.mod h1:qcDd6f25vJ0++wICwA1BainIcRC67p2Mb4lsrZ0k3/k= github.com/joshuarubin/lifecycle v1.0.0/go.mod h1:sRy++ATvR9Ee21tkRdFkQeywAWvDsue66V70K0Dnl54= @@ -29,18 +32,18 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 h1:lGdhQUN/cnWdSH3291CUuxSEqc+AsGTiDxPP3r2J0l4= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go index bb9d4f2..bfd7b9c 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "flag" "fmt" + "github.com/diamondburned/gotk4-layer-shell/pkg/gtklayershell" "github.com/expr-lang/expr" "os" "os/signal" @@ -13,16 +14,15 @@ import ( "syscall" "time" + "github.com/allan-simon/go-singleinstance" log "github.com/sirupsen/logrus" - "github.com/allan-simon/go-singleinstance" - "github.com/dlasky/gotk3-layershell/layershell" - "github.com/gotk3/gotk3/gdk" - "github.com/gotk3/gotk3/glib" - "github.com/gotk3/gotk3/gtk" + "github.com/diamondburned/gotk4/pkg/gdk/v3" + "github.com/diamondburned/gotk4/pkg/glib/v2" + "github.com/diamondburned/gotk4/pkg/gtk/v3" ) -const version = "0.5.2" +const version = "0.6.0" var ( appDirs []string @@ -387,91 +387,79 @@ func main() { } // USER INTERFACE - gtk.Init(nil) + gtk.Init() - settings, _ := gtk.SettingsGetDefault() + settings := gtk.SettingsGetDefault() if *gtkTheme != "" { - err = settings.SetProperty("gtk-theme-name", *gtkTheme) - if err != nil { - log.Error("Unable to set theme:", err) - } else { - log.Infof("User demanded theme: %s", *gtkTheme) - } + settings.SetObjectProperty("gtk-theme-name", *gtkTheme) + log.Infof("User demanded theme: %s", *gtkTheme) } else { - err := settings.SetProperty("gtk-application-prefer-dark-theme", true) - if err != nil { - log.Error("Error setting 'gtk-application-prefer-dark-theme' property") - return - } + settings.SetObjectProperty("gtk-application-prefer-dark-theme", true) log.Info("Preferring dark theme variants") } if *gtkIconTheme != "" { - err = settings.SetProperty("gtk-icon-theme-name", *gtkIconTheme) - if err != nil { - log.Error("Unable to set icon theme:", err) - } else { - log.Infof("User demanded icon theme: %s", *gtkIconTheme) - } + settings.SetObjectProperty("gtk-icon-theme-name", *gtkIconTheme) + log.Infof("User demanded icon theme: %s", *gtkIconTheme) } - cssProvider, _ := gtk.CssProviderNew() + cssProvider := gtk.NewCSSProvider() err = cssProvider.LoadFromPath(*cssFileName) if err != nil { log.Errorf("ERROR: %s css file not found or erroneous. Using GTK styling.", *cssFileName) } else { log.Info(fmt.Sprintf("Using style from %s", *cssFileName)) - screen, _ := gdk.ScreenGetDefault() - gtk.AddProviderForScreen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) + screen := gdk.ScreenGetDefault() + gtk.StyleContextAddProviderForScreen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) } - win, err = gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + win = gtk.NewWindow(gtk.WindowToplevel) if err != nil { log.Fatal("Unable to create window:", err) } if wayland() { - layershell.InitForWindow(win) - layershell.SetNamespace(win, "nwg-drawer") + gtklayershell.InitForWindow(win) + gtklayershell.SetNamespace(win, "nwg-drawer") var output2mon map[string]*gdk.Monitor if *targetOutput != "" { // We want to assign layershell to a monitor, but we only know the output name! output2mon, err = mapOutputs() - log.Debugf("output2mon: %s", output2mon) + log.Debugf("output2mon: %v", output2mon) if err == nil { - monitor := output2mon[*targetOutput] - layershell.SetMonitor(win, monitor) + mon := output2mon[*targetOutput] + gtklayershell.SetMonitor(win, mon) } else { log.Errorf("%s", err) } } - layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_BOTTOM, true) - layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_TOP, true) - layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_LEFT, true) - layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_RIGHT, true) + gtklayershell.SetAnchor(win, gtklayershell.LayerShellEdgeBottom, true) + gtklayershell.SetAnchor(win, gtklayershell.LayerShellEdgeTop, true) + gtklayershell.SetAnchor(win, gtklayershell.LayerShellEdgeLeft, true) + gtklayershell.SetAnchor(win, gtklayershell.LayerShellEdgeRight, true) if *overlay { - layershell.SetLayer(win, layershell.LAYER_SHELL_LAYER_OVERLAY) - layershell.SetExclusiveZone(win, -1) + gtklayershell.SetLayer(win, gtklayershell.LayerShellLayerOverlay) + gtklayershell.SetExclusiveZone(win, -1) } else { - layershell.SetLayer(win, layershell.LAYER_SHELL_LAYER_TOP) + gtklayershell.SetLayer(win, gtklayershell.LayerShellLayerTop) } - layershell.SetMargin(win, layershell.LAYER_SHELL_EDGE_TOP, *marginTop) - layershell.SetMargin(win, layershell.LAYER_SHELL_EDGE_LEFT, *marginLeft) - layershell.SetMargin(win, layershell.LAYER_SHELL_EDGE_RIGHT, *marginRight) - layershell.SetMargin(win, layershell.LAYER_SHELL_EDGE_BOTTOM, *marginBottom) + gtklayershell.SetMargin(win, gtklayershell.LayerShellEdgeTop, *marginTop) + gtklayershell.SetMargin(win, gtklayershell.LayerShellEdgeLeft, *marginLeft) + gtklayershell.SetMargin(win, gtklayershell.LayerShellEdgeRight, *marginRight) + gtklayershell.SetMargin(win, gtklayershell.LayerShellEdgeBottom, *marginBottom) if *keyboard { log.Info("Setting GTK layer shell keyboard mode to: on-demand") - layershell.SetKeyboardMode(win, layershell.LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND) + gtklayershell.SetKeyboardMode(win, gtklayershell.LayerShellKeyboardModeOnDemand) } else { log.Info("Setting GTK layer shell keyboard mode to default: exclusive") - layershell.SetKeyboardMode(win, layershell.LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE) + gtklayershell.SetKeyboardMode(win, gtklayershell.LayerShellKeyboardModeExclusive) } } @@ -481,9 +469,10 @@ func main() { }) win.Connect("key-release-event", func(_ *gtk.Window, event *gdk.Event) bool { - key := &gdk.EventKey{Event: event} - if key.KeyVal() == gdk.KEY_Escape { - s, _ := searchEntry.GetText() + //key := &gdk.EventKey{Event: event} + key := event.AsKey() + if key.Keyval() == gdk.KEY_Escape { + s := searchEntry.Text() if s != "" { searchEntry.GrabFocus() searchEntry.SetText("") @@ -496,18 +485,18 @@ func main() { } return true - } else if key.KeyVal() == gdk.KEY_Tab { + } else if key.Keyval() == gdk.KEY_Tab { if firstPowerBtn != nil { - firstPowerBtn.ToWidget().GrabFocus() + firstPowerBtn.GrabFocus() } - } else if key.KeyVal() == gdk.KEY_Return { - s, _ := searchEntry.GetText() + } else if key.Keyval() == gdk.KEY_Return { + s := searchEntry.Text() if s != "" { // Check if the search box content is an arithmetic expression. If so, display the result // and copy to the clipboard with wl-copy. - result, err := expr.Eval(s, nil) - if err == nil { + result, e := expr.Eval(s, nil) + if e == nil { log.Debugf("Setting up mathemathical operation result window. Operation: %s, result: %v", s, result) setUpOperationResultWindow(s, fmt.Sprintf("%v", result)) } @@ -518,8 +507,9 @@ func main() { }) win.Connect("key-press-event", func(_ *gtk.Window, event *gdk.Event) bool { - key := &gdk.EventKey{Event: event} - switch key.KeyVal() { + //key := &gdk.EventKey{Event: event} + key := event.AsKey() + switch key.Keyval() { case gdk.KEY_downarrow, gdk.KEY_Up, gdk.KEY_Down, gdk.KEY_Left, gdk.KEY_Right, gdk.KEY_Tab, gdk.KEY_Return, gdk.KEY_Page_Up, gdk.KEY_Page_Down, gdk.KEY_Home, gdk.KEY_End: return false @@ -544,10 +534,10 @@ func main() { } // Set up UI - outerVBox, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + outerVBox := gtk.NewBox(gtk.OrientationVertical, 0) win.Add(outerVBox) - searchBoxWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + searchBoxWrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) outerVBox.PackStart(searchBoxWrapper, false, false, 10) searchEntry = setUpSearchEntry() @@ -555,37 +545,38 @@ func main() { searchBoxWrapper.PackStart(searchEntry, true, false, 0) if !*noCats { - categoriesWrapper, _ = gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + categoriesWrapper = gtk.NewBox(gtk.OrientationHorizontal, 0) categoriesButtonBox := setUpCategoriesButtonBox() categoriesWrapper.PackStart(categoriesButtonBox, true, false, 0) outerVBox.PackStart(categoriesWrapper, false, false, 0) } - pinnedWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + pinnedWrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) outerVBox.PackStart(pinnedWrapper, false, false, 0) - pinnedFlowBoxWrapper, _ = gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + pinnedFlowBoxWrapper = gtk.NewBox(gtk.OrientationHorizontal, 0) outerVBox.PackStart(pinnedFlowBoxWrapper, false, false, 0) pinnedFlowBox = setUpPinnedFlowBox() - resultWindow, _ = gtk.ScrolledWindowNew(nil, nil) - resultWindow.SetEvents(int(gdk.ALL_EVENTS_MASK)) - resultWindow.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + resultWindow = gtk.NewScrolledWindow(nil, nil) + resultWindow.SetEvents(int(gdk.AllEventsMask)) + resultWindow.SetPolicy(gtk.PolicyAutomatic, gtk.PolicyAutomatic) // On touch screen we don't want the button-release-event to launch the app if the user just wanted to scroll the // window. Let's forbid doing so if the content has been scrolled. We will reset the value on button-press-event. // Resolves https://github.com/nwg-piotr/nwg-drawer/issues/110 - vAdj := resultWindow.GetVAdjustment() + vAdj := resultWindow.VAdjustment() vAdj.Connect("value-changed", func() { beenScrolled = true }) - hAdj := resultWindow.GetHAdjustment() + hAdj := resultWindow.HAdjustment() hAdj.Connect("value-changed", func() { beenScrolled = true }) resultWindow.Connect("button-release-event", func(_ *gtk.ScrolledWindow, event *gdk.Event) bool { - btnEvent := gdk.EventButtonNewFromEvent(event) + //btnEvent := gdk.EventButtonNewFromEvent(event) + btnEvent := event.AsButton() if btnEvent.Button() == 3 { if !*resident { gtk.MainQuit() @@ -598,35 +589,35 @@ func main() { }) outerVBox.PackStart(resultWindow, true, true, 10) - resultsWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + resultsWrapper := gtk.NewBox(gtk.OrientationVertical, 0) resultWindow.Add(resultsWrapper) - appSearchResultWrapper, _ = gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + appSearchResultWrapper = gtk.NewBox(gtk.OrientationVertical, 0) resultsWrapper.PackStart(appSearchResultWrapper, false, false, 0) appFlowBox = setUpAppsFlowBox(nil, "") // Focus 1st pinned item if any, otherwise focus 1st found app icon - var button gtk.IWidget - if pinnedFlowBox.GetChildren().Length() > 0 { - button, err = pinnedFlowBox.GetChildAtIndex(0).GetChild() + var button gtk.Widget + if len(pinnedFlowBox.Children()) > 0 { + button = pinnedFlowBox.ChildAtIndex(0).Widget } else { - button, err = appFlowBox.GetChildAtIndex(0).GetChild() + button = appFlowBox.ChildAtIndex(0).Widget } if err == nil { - button.ToWidget().GrabFocus() + button.GrabFocus() } userDirsMap = mapXdgUserDirs() log.Debugf("User dirs map: %s", userDirsMap) - placeholder, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + placeholder := gtk.NewBox(gtk.OrientationVertical, 0) resultsWrapper.PackStart(placeholder, true, true, 0) placeholder.SetSizeRequest(20, 20) if !*noFS { - wrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) - fileSearchResultWrapper, _ = gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) - fileSearchResultWrapper.SetProperty("name", "files-box") + wrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) + fileSearchResultWrapper = gtk.NewBox(gtk.OrientationHorizontal, 0) + fileSearchResultWrapper.SetObjectProperty("name", "files-box") wrapper.PackStart(fileSearchResultWrapper, true, false, 0) resultsWrapper.PackEnd(wrapper, false, false, 10) } @@ -634,13 +625,13 @@ func main() { // Power Button Bar if dataDirectory != "" { if *pbExit != "" || *pbLock != "" || *pbPoweroff != "" || *pbReboot != "" || *pbSleep != "" { - powerBarWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + powerBarWrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) outerVBox.PackStart(powerBarWrapper, false, false, 0) - powerButtonsWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + powerButtonsWrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) powerBarWrapper.PackStart(powerButtonsWrapper, true, false, 12) if *pbPoweroff != "" { - btn, _ := gtk.ButtonNew() + btn := gtk.NewButton() if !*pbUseIconTheme { btn = powerButton(filepath.Join(dataDirectory, "img/poweroff.svg"), *pbPoweroff) } else { @@ -650,7 +641,7 @@ func main() { firstPowerBtn = btn } if *pbSleep != "" { - btn, _ := gtk.ButtonNew() + btn := gtk.NewButton() if !*pbUseIconTheme { btn = powerButton(filepath.Join(dataDirectory, "img/sleep.svg"), *pbSleep) } else { @@ -660,7 +651,7 @@ func main() { firstPowerBtn = btn } if *pbReboot != "" { - btn, _ := gtk.ButtonNew() + btn := gtk.NewButton() if !*pbUseIconTheme { btn = powerButton(filepath.Join(dataDirectory, "img/reboot.svg"), *pbReboot) } else { @@ -670,7 +661,7 @@ func main() { firstPowerBtn = btn } if *pbExit != "" { - btn, _ := gtk.ButtonNew() + btn := gtk.NewButton() if !*pbUseIconTheme { btn = powerButton(filepath.Join(dataDirectory, "img/exit.svg"), *pbExit) } else { @@ -680,7 +671,7 @@ func main() { firstPowerBtn = btn } if *pbLock != "" { - btn, _ := gtk.ButtonNew() + btn := gtk.NewButton() if !*pbUseIconTheme { btn = powerButton(filepath.Join(dataDirectory, "img/lock.svg"), *pbLock) } else { @@ -694,21 +685,21 @@ func main() { log.Warn("Couldn't find data dir, power bar icons unavailable") } - statusLineWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) - statusLineWrapper.SetProperty("name", "status-line-wrapper") + statusLineWrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) + statusLineWrapper.SetObjectProperty("name", "status-line-wrapper") outerVBox.PackStart(statusLineWrapper, false, false, 10) - statusLabel, _ = gtk.LabelNew(status) - statusLabel.SetProperty("name", "status-label") + statusLabel = gtk.NewLabel(status) + statusLabel.SetObjectProperty("name", "status-label") statusLineWrapper.PackStart(statusLabel, true, false, 0) win.ShowAll() if !*noFS { - fileSearchResultWrapper.SetSizeRequest(appFlowBox.GetAllocatedWidth(), 1) + fileSearchResultWrapper.SetSizeRequest(appFlowBox.AllocatedWidth(), 1) fileSearchResultWrapper.Hide() } if !*noCats { - categoriesWrapper.SetSizeRequest(1, categoriesWrapper.GetAllocatedHeight()*2) + categoriesWrapper.SetSizeRequest(1, categoriesWrapper.AllocatedHeight()*2) } if *resident { win.Hide() @@ -742,14 +733,14 @@ func main() { fileSearchResultWrapper.Hide() } // focus 1st element - var button gtk.IWidget - if pinnedFlowBox.GetChildren().Length() > 0 { - button, err = pinnedFlowBox.GetChildAtIndex(0).GetChild() + var button gtk.Widget + if len(pinnedFlowBox.Children()) > 0 { + button = pinnedFlowBox.ChildAtIndex(0).Widget } else { - button, err = appFlowBox.GetChildAtIndex(0).GetChild() + button = appFlowBox.ChildAtIndex(0).Widget } if err == nil { - button.ToWidget().GrabFocus() + button.GrabFocus() } } @@ -785,13 +776,13 @@ func restoreStateAndHide() { // clear category filter (in gotk3 it means: rebuild, as we have no filtering here) appFlowBox = setUpAppsFlowBox(nil, "") for _, btn := range catButtons { - btn.SetImagePosition(gtk.POS_LEFT) + btn.SetImagePosition(gtk.PosLeft) btn.SetSizeRequest(0, 0) } // scroll to the top if resultWindow != nil { - resultWindow.GetVAdjustment().SetValue(0) + resultWindow.VAdjustment().SetValue(0) } t := time.Now() diff --git a/tools.go b/tools.go index af1aa62..1d6cb1e 100644 --- a/tools.go +++ b/tools.go @@ -20,22 +20,20 @@ import ( "syscall" "time" - "github.com/gotk3/gotk3/gdk" - "github.com/gotk3/gotk3/gtk" + "github.com/diamondburned/gotk4/pkg/gdk/v3" + "github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2" + "github.com/diamondburned/gotk4/pkg/gtk/v3" ) func wayland() bool { return os.Getenv("WAYLAND_DISPLAY") != "" || os.Getenv("XDG_SESSION_TYPE") == "wayland" } -func createPixbuf(icon string, size int) (*gdk.Pixbuf, error) { - iconTheme, err := gtk.IconThemeGetDefault() - if err != nil { - log.Fatal("Couldn't get default theme: ", err) - } +func createPixbuf(icon string, size int) (*gdkpixbuf.Pixbuf, error) { + iconTheme := gtk.IconThemeGetDefault() if strings.Contains(icon, "/") { - pixbuf, err := gdk.PixbufNewFromFileAtSize(icon, size, size) + pixbuf, err := gdkpixbuf.NewPixbufFromFileAtSize(icon, size, size) if err != nil { log.Errorf("%s", err) return nil, err @@ -47,18 +45,18 @@ func createPixbuf(icon string, size int) (*gdk.Pixbuf, error) { icon = strings.Split(icon, ".")[0] } - pixbuf, err := iconTheme.LoadIcon(icon, size, gtk.ICON_LOOKUP_FORCE_SIZE) + pixbuf, err := iconTheme.LoadIcon(icon, size, gtk.IconLookupForceSize) if err != nil { if strings.HasPrefix(icon, "/") { - pixbuf, err := gdk.PixbufNewFromFileAtSize(icon, size, size) - if err != nil { - return nil, err + pixbuf, e := gdkpixbuf.NewPixbufFromFileAtSize(icon, size, size) + if e != nil { + return nil, e } return pixbuf, nil } - pixbuf, err := iconTheme.LoadIcon(icon, size, gtk.ICON_LOOKUP_FORCE_SIZE) + pixbuf, err := iconTheme.LoadIcon(icon, size, gtk.IconLookupForceSize) if err != nil { return nil, err } @@ -581,19 +579,19 @@ func launch(command string, terminal bool, terminate bool) { } } - themeToPrepend := "" - // add "GTK_THEME=" environment variable - if *forceTheme { - settings, _ := gtk.SettingsGetDefault() - th, err := settings.GetProperty("gtk-theme-name") - if err == nil { - themeToPrepend = th.(string) - } - } - - if themeToPrepend != "" { - command = fmt.Sprintf("GTK_THEME=%q %s", themeToPrepend, command) - } + //themeToPrepend := "" + // add "GTK_THEME=" environment variable TODO fix + //if *forceTheme { + // settings := gtk.SettingsGetDefault() + // th, err := settings.GetProperty("gtk-theme-name") + // if err == nil { + // themeToPrepend = th.(string) + // } + //} + // + //if themeToPrepend != "" { + // command = fmt.Sprintf("GTK_THEME=%q %s", themeToPrepend, command) + //} var elements = []string{"/usr/bin/env", "-S", command} @@ -684,14 +682,11 @@ func mapOutputs() (map[string]*gdk.Monitor, error) { err := listHyprlandMonitors() if err == nil { - display, err := gdk.DisplayGetDefault() - if err != nil { - return nil, err - } + display := gdk.DisplayGetDefault() - num := display.GetNMonitors() + num := display.NMonitors() for i := 0; i < num; i++ { - mon, _ := display.GetMonitor(i) + mon := display.Monitor(i) output := hyprlandMonitors[i] result[output.Name] = mon } @@ -713,14 +708,14 @@ func mapOutputs() (map[string]*gdk.Monitor, error) { return nil, err } - display, err := gdk.DisplayGetDefault() + display := gdk.DisplayGetDefault() if err != nil { return nil, err } - num := display.GetNMonitors() + num := display.NMonitors() for i := 0; i < num; i++ { - mon, _ := display.GetMonitor(i) + mon := display.Monitor(i) output := outputs[i] result[output.Name] = mon } diff --git a/uicomponents.go b/uicomponents.go index c345cc4..64edb95 100644 --- a/uicomponents.go +++ b/uicomponents.go @@ -2,22 +2,23 @@ package main import ( "fmt" - "github.com/dlasky/gotk3-layershell/layershell" + "github.com/diamondburned/gotk4-layer-shell/pkg/gtklayershell" "io/fs" "path/filepath" "strings" log "github.com/sirupsen/logrus" - "github.com/gotk3/gotk3/gdk" - "github.com/gotk3/gotk3/gtk" + "github.com/diamondburned/gotk4/pkg/gdk/v3" + "github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2" + "github.com/diamondburned/gotk4/pkg/gtk/v3" ) func setUpPinnedFlowBox() *gtk.FlowBox { if pinnedFlowBox != nil { pinnedFlowBox.Destroy() } - flowBox, _ := gtk.FlowBoxNew() + flowBox := gtk.NewFlowBox() if uint(len(pinned)) >= *columnsNumber { flowBox.SetMaxChildrenPerLine(*columnsNumber) } else if len(pinned) > 0 { @@ -27,8 +28,8 @@ func setUpPinnedFlowBox() *gtk.FlowBox { flowBox.SetColumnSpacing(*itemSpacing) flowBox.SetRowSpacing(*itemSpacing) flowBox.SetHomogeneous(true) - flowBox.SetProperty("name", "pinned-box") - flowBox.SetSelectionMode(gtk.SELECTION_NONE) + flowBox.SetObjectProperty("name", "pinned-box") + flowBox.SetSelectionMode(gtk.SelectionNone) if len(pinned) > 0 { for _, desktopID := range pinned { @@ -38,19 +39,19 @@ func setUpPinnedFlowBox() *gtk.FlowBox { continue } - btn, _ := gtk.ButtonNew() + btn := gtk.NewButton() var img *gtk.Image if entry.Icon != "" { pixbuf, _ := createPixbuf(entry.Icon, *iconSize) - img, _ = gtk.ImageNewFromPixbuf(pixbuf) + img = gtk.NewImageFromPixbuf(pixbuf) } else { - img, _ = gtk.ImageNewFromIconName("image-missing", gtk.ICON_SIZE_INVALID) + img = gtk.NewImageFromIconName("image-missing", int(gtk.IconSizeInvalid)) } btn.SetImage(img) btn.SetAlwaysShowImage(true) - btn.SetImagePosition(gtk.POS_TOP) + btn.SetImagePosition(gtk.PosTop) name := "" if entry.NameLoc != "" { @@ -60,12 +61,12 @@ func setUpPinnedFlowBox() *gtk.FlowBox { } if len(name) > 20 { r := substring(name, 0, 17) - name = fmt.Sprintf("%s…", string(r)) + name = fmt.Sprintf("%s…", r) } btn.SetLabel(name) - btn.Connect("button-release-event", func(row *gtk.Button, e *gdk.Event) bool { - btnEvent := gdk.EventButtonNewFromEvent(e) + btn.Connect("button-release-event", func(row *gtk.Button, event *gdk.Event) bool { + btnEvent := event.AsButton() if btnEvent.Button() == 1 { launch(entry.Exec, entry.Terminal, true) return true @@ -85,13 +86,9 @@ func setUpPinnedFlowBox() *gtk.FlowBox { statusLabel.SetText(entry.CommentLoc) }) flowBox.Add(btn) + btn.Parent().(*gtk.FlowBoxChild).SetCanFocus(false) } pinnedFlowBoxWrapper.PackStart(flowBox, true, false, 0) - - //While moving focus with arrow keys we want buttons to get focus directly - flowBox.GetChildren().Foreach(func(item interface{}) { - item.(*gtk.Widget).SetCanFocus(false) - }) } flowBox.ShowAll() @@ -111,17 +108,17 @@ func setUpCategoriesButtonBox() *gtk.EventBox { "other": listOther, } - eventBox, _ := gtk.EventBoxNew() + eventBox := gtk.NewEventBox() - hBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + hBox := gtk.NewBox(gtk.OrientationHorizontal, 0) eventBox.Add(hBox) - button, _ := gtk.ButtonNewWithLabel("All") - button.SetProperty("name", "category-button") + button := gtk.NewButtonWithLabel("All") + button.SetObjectProperty("name", "category-button") button.Connect("clicked", func(item *gtk.Button) { searchEntry.SetText("") appFlowBox = setUpAppsFlowBox(nil, "") for _, btn := range catButtons { - btn.SetImagePosition(gtk.POS_LEFT) + btn.SetImagePosition(gtk.PosLeft) btn.SetSizeRequest(0, 0) } }) @@ -129,8 +126,8 @@ func setUpCategoriesButtonBox() *gtk.EventBox { for _, cat := range categories { if isSupposedToShowUp(cat.Name) { - button, _ = gtk.ButtonNewFromIconName(cat.Icon, gtk.ICON_SIZE_MENU) - button.SetProperty("name", "category-button") + button = gtk.NewButtonFromIconName(cat.Icon, int(gtk.IconSizeMenu)) + button.SetObjectProperty("name", "category-button") catButtons = append(catButtons, button) button.SetLabel(cat.DisplayName) button.SetAlwaysShowImage(true) @@ -142,10 +139,10 @@ func setUpCategoriesButtonBox() *gtk.EventBox { // !!! since gotk3 FlowBox type does not implement set_filter_func, we need to rebuild appFlowBox appFlowBox = setUpAppsFlowBox(lists[name], "") for _, btn := range catButtons { - btn.SetImagePosition(gtk.POS_LEFT) + btn.SetImagePosition(gtk.PosLeft) } - w := b.GetAllocatedWidth() - b.SetImagePosition(gtk.POS_TOP) + w := b.AllocatedWidth() + b.SetImagePosition(gtk.PosTop) b.SetSizeRequest(w, 0) if fileSearchResultWrapper != nil { fileSearchResultWrapper.Hide() @@ -187,13 +184,13 @@ func setUpAppsFlowBox(categoryList []string, searchPhrase string) *gtk.FlowBox { if appFlowBox != nil { appFlowBox.Destroy() } - flowBox, _ := gtk.FlowBoxNew() + flowBox := gtk.NewFlowBox() flowBox.SetMinChildrenPerLine(*columnsNumber) flowBox.SetMaxChildrenPerLine(*columnsNumber) flowBox.SetColumnSpacing(*itemSpacing) flowBox.SetRowSpacing(*itemSpacing) flowBox.SetHomogeneous(true) - flowBox.SetSelectionMode(gtk.SELECTION_NONE) + flowBox.SetSelectionMode(gtk.SelectionNone) for _, entry := range desktopEntries { if searchPhrase == "" { @@ -206,6 +203,7 @@ func setUpAppsFlowBox(categoryList []string, searchPhrase string) *gtk.FlowBox { } else { button := flowBoxButton(entry) flowBox.Add(button) + button.Parent().(*gtk.FlowBoxChild).SetCanFocus(false) } } } else { @@ -215,26 +213,24 @@ func setUpAppsFlowBox(categoryList []string, searchPhrase string) *gtk.FlowBox { strings.Contains(strings.ToLower(entry.Exec), strings.ToLower(searchPhrase))) { button := flowBoxButton(entry) flowBox.Add(button) + button.Parent().(*gtk.FlowBoxChild).SetCanFocus(false) } } } - hWrapper, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) + hWrapper := gtk.NewBox(gtk.OrientationHorizontal, 0) appSearchResultWrapper.PackStart(hWrapper, false, false, 0) hWrapper.PackStart(flowBox, true, false, 0) - // While moving focus with arrow keys we want buttons to get focus directly - flowBox.GetChildren().Foreach(func(item interface{}) { - item.(*gtk.Widget).SetCanFocus(false) - }) + resultWindow.ShowAll() return flowBox } func flowBoxButton(entry desktopEntry) *gtk.Button { - button, _ := gtk.ButtonNew() + button := gtk.NewButton() button.SetAlwaysShowImage(true) - var pixbuf *gdk.Pixbuf + var pixbuf *gdkpixbuf.Pixbuf var img *gtk.Image var err error if entry.Icon != "" { @@ -246,14 +242,14 @@ func flowBoxButton(entry desktopEntry) *gtk.Button { if err != nil { pixbuf, _ = createPixbuf("unknown", *iconSize) } - img, _ = gtk.ImageNewFromPixbuf(pixbuf) + img = gtk.NewImageFromPixbuf(pixbuf) button.SetImage(img) - button.SetImagePosition(gtk.POS_TOP) + button.SetImagePosition(gtk.PosTop) name := entry.NameLoc if len(name) > 20 { r := substring(name, 0, 17) - name = fmt.Sprintf("%s…", string(r)) + name = fmt.Sprintf("%s…", r) } button.SetLabel(name) @@ -263,7 +259,7 @@ func flowBoxButton(entry desktopEntry) *gtk.Button { desc := entry.CommentLoc if len(desc) > 120 { r := substring(desc, 0, 117) - desc = fmt.Sprintf("%s…", string(r)) + desc = fmt.Sprintf("%s…", r) } button.Connect("button-press-event", func() { @@ -271,8 +267,8 @@ func flowBoxButton(entry desktopEntry) *gtk.Button { beenScrolled = false }) - button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { - btnEvent := gdk.EventButtonNewFromEvent(e) + button.Connect("button-release-event", func(btn *gtk.Button, event *gdk.Event) bool { + btnEvent := event.AsButton() if btnEvent.Button() == 1 { if !beenScrolled { launch(exec, terminal, true) @@ -300,28 +296,28 @@ func flowBoxButton(entry desktopEntry) *gtk.Button { } func powerButton(iconPathOrName, command string) *gtk.Button { - button, _ := gtk.ButtonNew() + button := gtk.NewButton() button.SetAlwaysShowImage(true) - var pixbuf *gdk.Pixbuf + var pixbuf *gdkpixbuf.Pixbuf var img *gtk.Image var err error if !*pbUseIconTheme { - pixbuf, err = gdk.PixbufNewFromFileAtSize(iconPathOrName, *pbSize, *pbSize) + pixbuf, err = gdkpixbuf.NewPixbufFromFileAtSize(iconPathOrName, *pbSize, *pbSize) if err != nil { pixbuf, _ = createPixbuf("unknown", *pbSize) log.Warnf("Couldn't find icon %s", iconPathOrName) } - img, _ = gtk.ImageNewFromPixbuf(pixbuf) + img = gtk.NewImageFromPixbuf(pixbuf) } else { - img, _ = gtk.ImageNewFromIconName(iconPathOrName, gtk.ICON_SIZE_DIALOG) + img = gtk.NewImageFromIconName(iconPathOrName, int(gtk.IconSizeDialog)) } button.SetImage(img) - button.SetImagePosition(gtk.POS_TOP) + button.SetImagePosition(gtk.PosTop) - button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { - btnEvent := gdk.EventButtonNewFromEvent(e) + button.Connect("button-release-event", func(btn *gtk.Button, event *gdk.Event) bool { + btnEvent := event.AsButton() if btnEvent.Button() == 1 { launch(command, false, true) return true @@ -347,8 +343,8 @@ func setUpFileSearchResultContainer() *gtk.FlowBox { if fileSearchResultFlowBox != nil { fileSearchResultFlowBox.Destroy() } - flowBox, _ := gtk.FlowBoxNew() - flowBox.SetProperty("orientation", gtk.ORIENTATION_VERTICAL) + flowBox := gtk.NewFlowBox() + flowBox.SetObjectProperty("orientation", gtk.OrientationVertical) fileSearchResultWrapper.PackStart(flowBox, false, false, 10) return flowBox @@ -361,7 +357,7 @@ func walk(path string, d fs.DirEntry, e error) error { // don't search leading part of the path, as e.g. '/home/user/Pictures' toSearch := strings.Split(path, ignore)[1] - // Remaing part of the path (w/o file name) must be checked against being present in excluded dirs + // Remaining part of the path (w/o file name) must be checked against being present in excluded dirs doSearch := true parts := strings.Split(toSearch, "/") remainingPart := "" @@ -385,18 +381,15 @@ func walk(path string, d fs.DirEntry, e error) error { } func setUpSearchEntry() *gtk.SearchEntry { - searchEntry, _ := gtk.SearchEntryNew() - searchEntry.SetPlaceholderText("Type to search") - /*searchEntry.Connect("enter-notify-event", func() { - cancelClose() - })*/ - searchEntry.Connect("search-changed", func() { + sEntry := gtk.NewSearchEntry() + sEntry.SetPlaceholderText("Type to search") + sEntry.Connect("search-changed", func() { for _, btn := range catButtons { - btn.SetImagePosition(gtk.POS_LEFT) + btn.SetImagePosition(gtk.PosLeft) btn.SetSizeRequest(0, 0) } - phrase, _ = searchEntry.GetText() + phrase = sEntry.Text() if len(phrase) > 0 { // search apps @@ -416,7 +409,7 @@ func setUpSearchEntry() *gtk.SearchEntry { searchUserDir(key) } } - if fileSearchResultFlowBox.GetChildren().Length() == 0 { + if len(fileSearchResultFlowBox.Children()) == 0 { fileSearchResultWrapper.Hide() statusLabel.SetText("0 results") } @@ -430,25 +423,22 @@ func setUpSearchEntry() *gtk.SearchEntry { } } // focus 1st search result #17 - var w *gtk.Widget + var w *gtk.Button if appFlowBox != nil { - b := appFlowBox.GetChildAtIndex(0) + b := appFlowBox.ChildAtIndex(0) if b != nil { - button, err := b.GetChild() - if err == nil { - button.ToWidget().GrabFocus() - w = button.ToWidget() - } + button := b.Child().(*gtk.Button) + button.SetCanFocus(true) + button.GrabFocus() + w = button } } if w == nil && fileSearchResultFlowBox != nil { - f := fileSearchResultFlowBox.GetChildAtIndex(0) + f := fileSearchResultFlowBox.ChildAtIndex(0) if f != nil { - button, err := f.GetChild() - if err == nil { - button.ToWidget().SetCanFocus(true) - button.ToWidget().GrabFocus() - } + button := f.Child().(*gtk.Box) + button.SetCanFocus(true) + button.GrabFocus() } } } else { @@ -465,7 +455,7 @@ func setUpSearchEntry() *gtk.SearchEntry { } }) - return searchEntry + return sEntry } func isExcluded(dir string) bool { @@ -491,8 +481,9 @@ func searchUserDir(dir string) { partOfPathToShow := strings.Split(path, userDirsMap[dir])[1] if partOfPathToShow != "" { if !(strings.HasPrefix(path, "#is_dir#") && isExcluded(path)) { - btn := setUpUserFileSearchResultButton(partOfPathToShow, path) - fileSearchResultFlowBox.Add(btn) + button := setUpUserFileSearchResultButton(partOfPathToShow, path) + fileSearchResultFlowBox.Add(button) + button.Parent().(*gtk.FlowBoxChild).SetCanFocus(false) } } @@ -500,14 +491,11 @@ func searchUserDir(dir string) { fileSearchResultFlowBox.Hide() statusLabel.SetText(fmt.Sprintf("%v results | LMB: xdg-open | RMB: file manager", - fileSearchResultFlowBox.GetChildren().Length())) - num := uint(fileSearchResultFlowBox.GetChildren().Length() / *fsColumns) + len(fileSearchResultFlowBox.Children()))) + num := uint(len(fileSearchResultFlowBox.Children())) / *fsColumns fileSearchResultFlowBox.SetMinChildrenPerLine(num + 1) fileSearchResultFlowBox.SetMaxChildrenPerLine(num + 1) - //While moving focus with arrow keys we want buttons to get focus directly - fileSearchResultFlowBox.GetChildren().Foreach(func(item interface{}) { - item.(*gtk.Widget).SetCanFocus(false) - }) + fileSearchResultFlowBox.ShowAll() } } @@ -517,10 +505,10 @@ func setUpUserDirButton(iconName, displayName, entryName string, userDirsMap map parts := strings.Split(userDirsMap[entryName], "/") displayName = parts[(len(parts) - 1)] } - box, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) - button, _ := gtk.ButtonNew() + box := gtk.NewBox(gtk.OrientationHorizontal, 0) + button := gtk.NewButton() button.SetAlwaysShowImage(true) - img, _ := gtk.ImageNewFromIconName(iconName, gtk.ICON_SIZE_MENU) + img := gtk.NewImageFromIconName(iconName, int(gtk.IconSizeMenu)) button.SetImage(img) if len(displayName) > *nameLimit { @@ -528,8 +516,8 @@ func setUpUserDirButton(iconName, displayName, entryName string, userDirsMap map } button.SetLabel(displayName) - button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { - btnEvent := gdk.EventButtonNewFromEvent(e) + button.Connect("button-release-event", func(btn *gtk.Button, event *gdk.Event) bool { + btnEvent := event.AsButton() if btnEvent.Button() == 1 { open(userDirsMap[entryName], true) return true @@ -545,13 +533,13 @@ func setUpUserDirButton(iconName, displayName, entryName string, userDirsMap map } func setUpUserFileSearchResultButton(fileName, filePath string) *gtk.Box { - box, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) - button, _ := gtk.ButtonNew() + box := gtk.NewBox(gtk.OrientationHorizontal, 0) + button := gtk.NewButton() // in the walk function we've marked directories with the '#is_dir#' prefix if strings.HasPrefix(filePath, "#is_dir#") { filePath = filePath[8:] - img, _ := gtk.ImageNewFromIconName("folder", gtk.ICON_SIZE_MENU) + img := gtk.NewImageFromIconName("folder", int(gtk.IconSizeMenu)) button.SetAlwaysShowImage(true) button.SetImage(img) } @@ -566,8 +554,8 @@ func setUpUserFileSearchResultButton(fileName, filePath string) *gtk.Box { button.SetTooltipText(tooltipText) } - button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { - btnEvent := gdk.EventButtonNewFromEvent(e) + button.Connect("button-release-event", func(btn *gtk.Button, event *gdk.Event) bool { + btnEvent := event.AsButton() if btnEvent.Button() == 1 { open(filePath, true) return true @@ -581,55 +569,51 @@ func setUpUserFileSearchResultButton(fileName, filePath string) *gtk.Box { button.Connect("activate", func() { open(filePath, true) }) - box.PackStart(button, false, true, 0) return box } func setUpOperationResultWindow(operation string, result string) { - win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) - if err != nil { - log.Fatal("Unable to create result window:", err) - } - win.SetModal(true) + window := gtk.NewWindow(gtk.WindowToplevel) + window.SetModal(true) if wayland() { - layershell.InitForWindow(win) - layershell.SetLayer(win, layershell.LAYER_SHELL_LAYER_OVERLAY) - layershell.SetKeyboardMode(win, layershell.LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE) + gtklayershell.InitForWindow(window) + gtklayershell.SetLayer(window, gtklayershell.LayerShellLayerOverlay) + gtklayershell.SetKeyboardMode(window, gtklayershell.LayerShellKeyboardModeExclusive) } // any key to close the window - win.Connect("key-release-event", func(_ *gtk.Window, event *gdk.Event) bool { - win.Destroy() + window.Connect("key-release-event", func(_ *gtk.Window, event *gdk.Event) bool { + window.Destroy() return true }) // any button to close the window - win.Connect("button-release-event", func(_ *gtk.Window, event *gdk.Event) bool { - win.Destroy() + window.Connect("button-release-event", func(_ *gtk.Window, event *gdk.Event) bool { + window.Destroy() return true }) - outerVBox, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 6) - win.Add(outerVBox) + outerVBox := gtk.NewBox(gtk.OrientationVertical, 6) + window.Add(outerVBox) - vBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 5) + vBox := gtk.NewBox(gtk.OrientationHorizontal, 5) outerVBox.PackStart(vBox, true, true, 6) - lbl, _ := gtk.LabelNew(fmt.Sprintf("%s = %s", operation, result)) - lbl.SetProperty("name", "math-label") + lbl := gtk.NewLabel(fmt.Sprintf("%s = %s", operation, result)) + lbl.SetObjectProperty("name", "math-label") vBox.PackStart(lbl, true, true, 12) - mRefProvider, _ := gtk.CssProviderNew() + mRefProvider := gtk.NewCSSProvider() css := "window { background-color: rgba (0, 0, 0, 255); color: #fff; border: solid 1px grey; border-radius: 5px}" - err = mRefProvider.LoadFromData(css) + err := mRefProvider.LoadFromData(css) if err != nil { log.Warn(err) } - ctx, _ := win.GetStyleContext() + ctx := window.StyleContext() ctx.AddProvider(mRefProvider, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - win.ShowAll() + window.ShowAll() if wayland() { cmd := fmt.Sprintf("wl-copy %v", result)