7 Commits

Author SHA1 Message Date
Piotr Miller
be6b71673d Merge pull request #131 from nwg-piotr/calc
add a simple calculator in the search box
2024-10-03 01:20:01 +02:00
piotr
9c48c585b7 add rounded corners 2024-10-03 01:10:35 +02:00
piotr
3977c4fc7c go -> 1.23 2024-10-03 01:05:14 +02:00
piotr
46a526ced8 close result win on btn release 2024-10-03 01:04:53 +02:00
piotr
12da77fbfc update README.md 2024-10-03 00:48:23 +02:00
piotr
484c6ccb29 add comments 2024-10-03 00:33:54 +02:00
piotr
7aac5a4f52 add expression calculator 2024-09-30 22:09:56 +02:00
6 changed files with 94 additions and 16 deletions

View File

@@ -206,6 +206,12 @@ You may want to exclude some paths inside your XDG user directories from searchi
node_modules node_modules
``` ```
### Calculations in the search box
If the search box is not empty, and you press Enter, the search box content will be evaluated as an arithmetic operation.
If the result is not an error, it will be displayed in a small window, and copied to the clipboard with wl-copy.
Press any key to close the window.
## Credits ## Credits
This program uses some great libraries: This program uses some great libraries:
@@ -217,3 +223,4 @@ Copyright (c) 2015-2018 gotk3 contributors
- [go-singleinstance](github.com/allan-simon/go-singleinstance) Copyright (c) 2015 Allan Simon - [go-singleinstance](github.com/allan-simon/go-singleinstance) Copyright (c) 2015 Allan Simon
- [logrus](https://github.com/sirupsen/logrus) Copyright (c) 2014 Simon Eskildsen - [logrus](https://github.com/sirupsen/logrus) Copyright (c) 2014 Simon Eskildsen
- [fsnotify](https://github.com/fsnotify/fsnotify) Copyright (c) 2012-2019 fsnotify Authors - [fsnotify](https://github.com/fsnotify/fsnotify) Copyright (c) 2012-2019 fsnotify Authors
- [expr](https://github.com/expr-lang/expr) Copyright (c) 2018 Anton Medvedev

3
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/nwg-piotr/nwg-drawer module github.com/nwg-piotr/nwg-drawer
go 1.22 go 1.23
require ( require (
github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37
@@ -12,6 +12,7 @@ require (
) )
require ( require (
github.com/expr-lang/expr v1.16.9 // indirect
github.com/joshuarubin/lifecycle v1.1.4 // indirect github.com/joshuarubin/lifecycle v1.1.4 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.8.0 // indirect

2
go.sum
View File

@@ -5,6 +5,8 @@ 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/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 h1:o87OVL4olQBlVwN3+NSVQpS6gj9FWUYtxOfHXWZigUE=
github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774/go.mod h1:JHLx2Wz4mAPVwn4PFhC69ydwyHP4A3wQvlg7HKVVc1U= github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774/go.mod h1:JHLx2Wz4mAPVwn4PFhC69ydwyHP4A3wQvlg7HKVVc1U=
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 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 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.1/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=

21
main.go
View File

@@ -3,6 +3,7 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/expr-lang/expr"
"os" "os"
"os/signal" "os/signal"
"path" "path"
@@ -21,7 +22,7 @@ import (
"github.com/gotk3/gotk3/gtk" "github.com/gotk3/gotk3/gtk"
) )
const version = "0.5.0" const version = "0.5.1"
var ( var (
appDirs []string appDirs []string
@@ -493,12 +494,26 @@ func main() {
} }
} }
return true return true
} else if key.KeyVal() == gdk.KEY_Tab { } else if key.KeyVal() == gdk.KEY_Tab {
if firstPowerBtn != nil { if firstPowerBtn != nil {
firstPowerBtn.ToWidget().GrabFocus() firstPowerBtn.ToWidget().GrabFocus()
} }
} else if key.KeyVal() == gdk.KEY_Return {
s, _ := searchEntry.GetText()
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 {
log.Debugf("Setting up mathemathical operation result window. Operation: %s, result: %v", s, result)
setUpOperationResultWindow(s, fmt.Sprintf("%v", result))
} }
return false }
return true
}
return true
}) })
win.Connect("key-press-event", func(_ *gtk.Window, event *gdk.Event) bool { win.Connect("key-press-event", func(_ *gtk.Window, event *gdk.Event) bool {
@@ -512,8 +527,8 @@ func main() {
if !searchEntry.IsFocus() { if !searchEntry.IsFocus() {
searchEntry.GrabFocusWithoutSelecting() searchEntry.GrabFocusWithoutSelecting()
} }
return false
} }
return false
}) })
/* /*

View File

@@ -571,7 +571,7 @@ func savePinned() {
} }
} }
func launch(command string, terminal bool) { func launch(command string, terminal bool, terminate bool) {
// trim % and everything afterwards // trim % and everything afterwards
if strings.Contains(command, "%") { if strings.Contains(command, "%") {
cutAt := strings.Index(command, "%") cutAt := strings.Index(command, "%")
@@ -615,7 +615,7 @@ func launch(command string, terminal bool) {
cmd = exec.Command("riverctl", "spawn", strings.Join(elements, " ")) cmd = exec.Command("riverctl", "spawn", strings.Join(elements, " "))
} }
msg := fmt.Sprintf("command: %q; args: %q\n", cmd.Args[0], cmd.Args[1:]) msg := fmt.Sprintf("Executing command: %q; args: %q\n", cmd.Args[0], cmd.Args[1:])
log.Info(msg) log.Info(msg)
cmd.SysProcAttr = &syscall.SysProcAttr{ cmd.SysProcAttr = &syscall.SysProcAttr{
@@ -632,11 +632,13 @@ func launch(command string, terminal bool) {
}() }()
} }
if terminate {
if *resident { if *resident {
restoreStateAndHide() restoreStateAndHide()
} else { } else {
gtk.MainQuit() gtk.MainQuit()
} }
}
} }
func open(filePath string, xdgOpen bool) { func open(filePath string, xdgOpen bool) {

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/dlasky/gotk3-layershell/layershell"
"io/fs" "io/fs"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -66,7 +67,7 @@ func setUpPinnedFlowBox() *gtk.FlowBox {
btn.Connect("button-release-event", func(row *gtk.Button, e *gdk.Event) bool { btn.Connect("button-release-event", func(row *gtk.Button, e *gdk.Event) bool {
btnEvent := gdk.EventButtonNewFromEvent(e) btnEvent := gdk.EventButtonNewFromEvent(e)
if btnEvent.Button() == 1 { if btnEvent.Button() == 1 {
launch(entry.Exec, entry.Terminal) launch(entry.Exec, entry.Terminal, true)
return true return true
} else if btnEvent.Button() == 3 { } else if btnEvent.Button() == 3 {
unpinItem(entry.DesktopID) unpinItem(entry.DesktopID)
@@ -75,7 +76,7 @@ func setUpPinnedFlowBox() *gtk.FlowBox {
return false return false
}) })
btn.Connect("activate", func() { btn.Connect("activate", func() {
launch(entry.Exec, entry.Terminal) launch(entry.Exec, entry.Terminal, true)
}) })
btn.Connect("enter-notify-event", func() { btn.Connect("enter-notify-event", func() {
statusLabel.SetText(entry.CommentLoc) statusLabel.SetText(entry.CommentLoc)
@@ -274,7 +275,7 @@ func flowBoxButton(entry desktopEntry) *gtk.Button {
btnEvent := gdk.EventButtonNewFromEvent(e) btnEvent := gdk.EventButtonNewFromEvent(e)
if btnEvent.Button() == 1 { if btnEvent.Button() == 1 {
if !beenScrolled { if !beenScrolled {
launch(exec, terminal) launch(exec, terminal, true)
return true return true
} }
} else if btnEvent.Button() == 3 { } else if btnEvent.Button() == 3 {
@@ -284,7 +285,7 @@ func flowBoxButton(entry desktopEntry) *gtk.Button {
return false return false
}) })
button.Connect("activate", func() { button.Connect("activate", func() {
launch(exec, terminal) launch(exec, terminal, true)
}) })
button.Connect("enter-notify-event", func() { button.Connect("enter-notify-event", func() {
statusLabel.SetText(desc) statusLabel.SetText(desc)
@@ -322,13 +323,13 @@ func powerButton(iconPathOrName, command string) *gtk.Button {
button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool {
btnEvent := gdk.EventButtonNewFromEvent(e) btnEvent := gdk.EventButtonNewFromEvent(e)
if btnEvent.Button() == 1 { if btnEvent.Button() == 1 {
launch(command, false) launch(command, false, true)
return true return true
} }
return false return false
}) })
button.Connect("activate", func() { button.Connect("activate", func() {
launch(command, false) launch(command, false, true)
}) })
button.Connect("enter-notify-event", func() { button.Connect("enter-notify-event", func() {
statusLabel.SetText(command) statusLabel.SetText(command)
@@ -584,3 +585,53 @@ func setUpUserFileSearchResultButton(fileName, filePath string) *gtk.Box {
box.PackStart(button, false, true, 0) box.PackStart(button, false, true, 0)
return box 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)
if wayland() {
layershell.InitForWindow(win)
layershell.SetLayer(win, layershell.LAYER_SHELL_LAYER_OVERLAY)
layershell.SetKeyboardMode(win, layershell.LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE)
}
// any key to close the window
win.Connect("key-release-event", func(_ *gtk.Window, event *gdk.Event) bool {
win.Destroy()
return true
})
// any button to close the window
win.Connect("button-release-event", func(_ *gtk.Window, event *gdk.Event) bool {
win.Destroy()
return true
})
outerVBox, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 6)
win.Add(outerVBox)
vBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 5)
outerVBox.PackStart(vBox, true, true, 6)
lbl, _ := gtk.LabelNew(fmt.Sprintf("%s = %s", operation, result))
vBox.PackStart(lbl, true, true, 12)
mRefProvider, _ := gtk.CssProviderNew()
css := "window { background-color: rgba (0, 0, 0, 255); color: #fff; font-weight: bold; border: solid 1px grey; border-radius: 5px}"
err = mRefProvider.LoadFromData(css)
if err != nil {
log.Warn(err)
}
ctx, _ := win.GetStyleContext()
ctx.AddProvider(mRefProvider, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
win.ShowAll()
if wayland() {
cmd := fmt.Sprintf("wl-copy %v", result)
launch(cmd, false, false)
}
}