Merge pull request #2 from nwg-piotr/cleaning
Code cleanup; support for the XDG_DATA_HOME value; and more
This commit is contained in:
BIN
bin/nwg-drawer
BIN
bin/nwg-drawer
Binary file not shown.
2
go.mod
2
go.mod
@@ -5,6 +5,6 @@ go 1.16
|
|||||||
require (
|
require (
|
||||||
github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37
|
github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37
|
||||||
github.com/dlasky/gotk3-layershell v0.0.0-20210331230524-5cca0b819261
|
github.com/dlasky/gotk3-layershell v0.0.0-20210331230524-5cca0b819261
|
||||||
github.com/gotk3/gotk3 v0.5.3-0.20210223154815-289cfb6dbf32
|
github.com/gotk3/gotk3 v0.6.0
|
||||||
github.com/joshuarubin/go-sway v0.0.4
|
github.com/joshuarubin/go-sway v0.0.4
|
||||||
)
|
)
|
||||||
|
|||||||
5
go.sum
5
go.sum
@@ -4,10 +4,9 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dlasky/gotk3-layershell v0.0.0-20210331230524-5cca0b819261 h1:eoXn91ckLWKMXmQKX34UHEF2XMyQpRnnP80fDiu+kys=
|
github.com/dlasky/gotk3-layershell v0.0.0-20210331230524-5cca0b819261 h1:eoXn91ckLWKMXmQKX34UHEF2XMyQpRnnP80fDiu+kys=
|
||||||
github.com/dlasky/gotk3-layershell v0.0.0-20210331230524-5cca0b819261/go.mod h1:d56Gslp3IaiT8lqxD/lO1Msz1wYgD8D/HTKHgSdg9tU=
|
github.com/dlasky/gotk3-layershell v0.0.0-20210331230524-5cca0b819261/go.mod h1:d56Gslp3IaiT8lqxD/lO1Msz1wYgD8D/HTKHgSdg9tU=
|
||||||
github.com/gotk3/gotk3 v0.5.3-0.20210223154815-289cfb6dbf32 h1:wE6C/HgLUBHi8YhHlCEulrmQMntVl4PFdh3kA0sWyAY=
|
|
||||||
github.com/gotk3/gotk3 v0.5.3-0.20210223154815-289cfb6dbf32/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
github.com/gotk3/gotk3 v0.5.3-0.20210223154815-289cfb6dbf32/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
||||||
github.com/joshuarubin/go-sway v0.0.3 h1:uuY+dAMz+iAJvso+DP7TSRczDWhaV47nEPHJoRDOqjA=
|
github.com/gotk3/gotk3 v0.6.0 h1:Aqlq4/6VabNwtCyA9M9zFNad5yHAqCi5heWnZ9y+3dA=
|
||||||
github.com/joshuarubin/go-sway v0.0.3/go.mod h1:qcDd6f25vJ0++wICwA1BainIcRC67p2Mb4lsrZ0k3/k=
|
github.com/gotk3/gotk3 v0.6.0/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
||||||
github.com/joshuarubin/go-sway v0.0.4 h1:dpmIwQ/LytG+oMrjmaVKdk1aPdW2feXK/+wAcLKIx4A=
|
github.com/joshuarubin/go-sway v0.0.4 h1:dpmIwQ/LytG+oMrjmaVKdk1aPdW2feXK/+wAcLKIx4A=
|
||||||
github.com/joshuarubin/go-sway v0.0.4/go.mod h1:qcDd6f25vJ0++wICwA1BainIcRC67p2Mb4lsrZ0k3/k=
|
github.com/joshuarubin/go-sway v0.0.4/go.mod h1:qcDd6f25vJ0++wICwA1BainIcRC67p2Mb4lsrZ0k3/k=
|
||||||
github.com/joshuarubin/lifecycle v1.0.0 h1:N/lPEC8f+dBZ1Tn99vShqp36LwB+LI7XNAiNadZeLUQ=
|
github.com/joshuarubin/lifecycle v1.0.0 h1:N/lPEC8f+dBZ1Tn99vShqp36LwB+LI7XNAiNadZeLUQ=
|
||||||
|
|||||||
37
main.go
37
main.go
@@ -19,19 +19,15 @@ import (
|
|||||||
"github.com/gotk3/gotk3/gtk"
|
"github.com/gotk3/gotk3/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "0.0.2"
|
const version = "0.1.0"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
appDirs []string
|
appDirs []string
|
||||||
configDirectory string
|
configDirectory string
|
||||||
pinnedFile string
|
pinnedFile string
|
||||||
pinned []string
|
pinned []string
|
||||||
rightBox *gtk.Box
|
src glib.SourceHandle
|
||||||
src glib.SourceHandle
|
id2entry map[string]desktopEntry
|
||||||
imgSizeScaled int
|
|
||||||
currentWsNum, targetWsNum int64
|
|
||||||
win *gtk.Window
|
|
||||||
id2entry map[string]desktopEntry
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var categoryNames = [...]string{
|
var categoryNames = [...]string{
|
||||||
@@ -87,10 +83,7 @@ var (
|
|||||||
fileSearchResults []string
|
fileSearchResults []string
|
||||||
searchEntry *gtk.SearchEntry
|
searchEntry *gtk.SearchEntry
|
||||||
phrase string
|
phrase string
|
||||||
fileSearchResultListBox *gtk.ListBox // tbd
|
|
||||||
fileSearchResultFlowBox *gtk.FlowBox
|
fileSearchResultFlowBox *gtk.FlowBox
|
||||||
buttonsWrapper *gtk.Box
|
|
||||||
buttonBox *gtk.EventBox
|
|
||||||
userDirsMap map[string]string
|
userDirsMap map[string]string
|
||||||
appFlowBox *gtk.FlowBox
|
appFlowBox *gtk.FlowBox
|
||||||
appSearchResultWrapper *gtk.Box
|
appSearchResultWrapper *gtk.Box
|
||||||
@@ -100,7 +93,6 @@ var (
|
|||||||
catButtons []*gtk.Button
|
catButtons []*gtk.Button
|
||||||
statusLabel *gtk.Label
|
statusLabel *gtk.Label
|
||||||
status string
|
status string
|
||||||
mainColumnWidth int
|
|
||||||
ignore string
|
ignore string
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -166,7 +158,7 @@ func main() {
|
|||||||
configDirectory = configDir()
|
configDirectory = configDir()
|
||||||
|
|
||||||
if !pathExists(filepath.Join(configDirectory, "drawer.css")) {
|
if !pathExists(filepath.Join(configDirectory, "drawer.css")) {
|
||||||
copyFile("/usr/share/nwg-drawer/drawer.css", filepath.Join(configDirectory, "drawer.css"))
|
copyFile(filepath.Join(getDataHome(), "nwg-drawer/drawer.css"), filepath.Join(configDirectory, "drawer.css"))
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheDirectory := cacheDir()
|
cacheDirectory := cacheDir()
|
||||||
@@ -272,7 +264,7 @@ func main() {
|
|||||||
|
|
||||||
// Close the window on leave, but not immediately, to avoid accidental closes
|
// Close the window on leave, but not immediately, to avoid accidental closes
|
||||||
win.Connect("leave-notify-event", func() {
|
win.Connect("leave-notify-event", func() {
|
||||||
src, err = glib.TimeoutAdd(uint(500), func() bool {
|
src = glib.TimeoutAdd(uint(500), func() bool {
|
||||||
gtk.MainQuit()
|
gtk.MainQuit()
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
@@ -319,6 +311,17 @@ func main() {
|
|||||||
resultsWrapper.PackStart(appSearchResultWrapper, false, false, 0)
|
resultsWrapper.PackStart(appSearchResultWrapper, false, false, 0)
|
||||||
appFlowBox = setUpAppsFlowBox(nil, "")
|
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()
|
||||||
|
} else {
|
||||||
|
button, err = appFlowBox.GetChildAtIndex(0).GetChild()
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
button.ToWidget().GrabFocus()
|
||||||
|
}
|
||||||
|
|
||||||
userDirsMap = mapXdgUserDirs()
|
userDirsMap = mapXdgUserDirs()
|
||||||
|
|
||||||
placeholder, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
|
placeholder, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
|
||||||
|
|||||||
32
tools.go
32
tools.go
@@ -21,9 +21,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Window on-leave-notify event hides the window with glib Timeout 1000 ms.
|
Window leave-notify-event event quits the program with glib Timeout 500 ms.
|
||||||
We might have left the window by accident, so let's clear the timeout if window re-entered.
|
We might have left the window by accident, so let's clear the timeout if window re-entered.
|
||||||
Furthermore - hovering a widget triggers window on-leave-notify event, and the timeout
|
Furthermore - hovering a widget triggers window leave-notify-event event, and the timeout
|
||||||
needs to be cleared as well.
|
needs to be cleared as well.
|
||||||
*/
|
*/
|
||||||
func cancelClose() {
|
func cancelClose() {
|
||||||
@@ -33,15 +33,6 @@ func cancelClose() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func inPinned(taskID string) bool {
|
|
||||||
for _, id := range pinned {
|
|
||||||
if strings.TrimSpace(taskID) == strings.TrimSpace(id) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func createPixbuf(icon string, size int) (*gdk.Pixbuf, error) {
|
func createPixbuf(icon string, size int) (*gdk.Pixbuf, error) {
|
||||||
iconTheme, err := gtk.IconThemeGetDefault()
|
iconTheme, err := gtk.IconThemeGetDefault()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -57,7 +48,7 @@ func createPixbuf(icon string, size int) (*gdk.Pixbuf, error) {
|
|||||||
return pixbuf, nil
|
return pixbuf, nil
|
||||||
|
|
||||||
} else if strings.HasSuffix(icon, ".svg") || strings.HasSuffix(icon, ".png") || strings.HasSuffix(icon, ".xpm") {
|
} else if strings.HasSuffix(icon, ".svg") || strings.HasSuffix(icon, ".png") || strings.HasSuffix(icon, ".xpm") {
|
||||||
// for enties like "Icon=netflix-desktop.svg"
|
// for entries like "Icon=netflix-desktop.svg"
|
||||||
icon = strings.Split(icon, ".")[0]
|
icon = strings.Split(icon, ".")[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,6 +202,13 @@ func copyFile(src, dst string) error {
|
|||||||
return os.Chmod(dst, srcinfo.Mode())
|
return os.Chmod(dst, srcinfo.Mode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDataHome() string {
|
||||||
|
if os.Getenv("XDG_DATA_HOME") != "" {
|
||||||
|
return os.Getenv("XDG_DATA_HOME")
|
||||||
|
}
|
||||||
|
return "/usr/share/"
|
||||||
|
}
|
||||||
|
|
||||||
func getAppDirs() []string {
|
func getAppDirs() []string {
|
||||||
var dirs []string
|
var dirs []string
|
||||||
xdgDataDirs := ""
|
xdgDataDirs := ""
|
||||||
@@ -266,7 +264,7 @@ func listDesktopFiles() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setUpCategories() {
|
func setUpCategories() {
|
||||||
path := "/usr/share/nwg-menu/desktop-directories"
|
path := filepath.Join(getDataHome(), "nwg-menu/desktop-directories")
|
||||||
var other category
|
var other category
|
||||||
|
|
||||||
for _, cName := range categoryNames {
|
for _, cName := range categoryNames {
|
||||||
@@ -373,9 +371,7 @@ func parseDesktopFiles(desktopFiles []string) string {
|
|||||||
exec = strings.Split(l, "Exec=")[1]
|
exec = strings.Split(l, "Exec=")[1]
|
||||||
disallowed := [2]string{"\"", "'"}
|
disallowed := [2]string{"\"", "'"}
|
||||||
for _, char := range disallowed {
|
for _, char := range disallowed {
|
||||||
if strings.Contains(exec, char) {
|
exec = strings.Replace(exec, char, "", -1)
|
||||||
exec = strings.Replace(exec, char, "", -1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -606,9 +602,7 @@ func launch(command string, terminal bool) {
|
|||||||
// set env variables
|
// set env variables
|
||||||
if len(envVars) > 0 {
|
if len(envVars) > 0 {
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
for _, envVar := range envVars {
|
cmd.Env = append(cmd.Env, envVars...)
|
||||||
cmd.Env = append(cmd.Env, envVar)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := fmt.Sprintf("env vars: %s; command: '%s'; args: %s\n", envVars, elements[cmdIdx], elements[1+cmdIdx:])
|
msg := fmt.Sprintf("env vars: %s; command: '%s'; args: %s\n", envVars, elements[cmdIdx], elements[1+cmdIdx:])
|
||||||
|
|||||||
@@ -32,11 +32,15 @@ func setUpPinnedFlowBox() *gtk.FlowBox {
|
|||||||
entry := id2entry[desktopID]
|
entry := id2entry[desktopID]
|
||||||
|
|
||||||
btn, _ := gtk.ButtonNew()
|
btn, _ := gtk.ButtonNew()
|
||||||
pixbuf, _ := createPixbuf(entry.Icon, *iconSize)
|
|
||||||
img, err := gtk.ImageNewFromPixbuf(pixbuf)
|
var img *gtk.Image
|
||||||
if err != nil {
|
if entry.Icon != "" {
|
||||||
println(err, entry.Icon)
|
pixbuf, _ := createPixbuf(entry.Icon, *iconSize)
|
||||||
|
img, _ = gtk.ImageNewFromPixbuf(pixbuf)
|
||||||
|
} else {
|
||||||
|
img, _ = gtk.ImageNewFromIconName("image-missing", gtk.ICON_SIZE_INVALID)
|
||||||
}
|
}
|
||||||
|
|
||||||
btn.SetImage(img)
|
btn.SetImage(img)
|
||||||
btn.SetAlwaysShowImage(true)
|
btn.SetAlwaysShowImage(true)
|
||||||
btn.SetImagePosition(gtk.POS_TOP)
|
btn.SetImagePosition(gtk.POS_TOP)
|
||||||
@@ -164,7 +168,7 @@ func notEmpty(listCategory []string) bool {
|
|||||||
}
|
}
|
||||||
for _, desktopID := range listCategory {
|
for _, desktopID := range listCategory {
|
||||||
entry := id2entry[desktopID]
|
entry := id2entry[desktopID]
|
||||||
if entry.NoDisplay == false {
|
if !entry.NoDisplay {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,8 +226,14 @@ func flowBoxButton(entry desktopEntry) *gtk.Button {
|
|||||||
button, _ := gtk.ButtonNew()
|
button, _ := gtk.ButtonNew()
|
||||||
button.SetAlwaysShowImage(true)
|
button.SetAlwaysShowImage(true)
|
||||||
|
|
||||||
pixbuf, _ := createPixbuf(entry.Icon, *iconSize)
|
var img *gtk.Image
|
||||||
img, _ := gtk.ImageNewFromPixbuf(pixbuf)
|
if entry.Icon != "" {
|
||||||
|
pixbuf, _ := createPixbuf(entry.Icon, *iconSize)
|
||||||
|
img, _ = gtk.ImageNewFromPixbuf(pixbuf)
|
||||||
|
} else {
|
||||||
|
img, _ = gtk.ImageNewFromIconName("image-missing", gtk.ICON_SIZE_INVALID)
|
||||||
|
}
|
||||||
|
|
||||||
button.SetImage(img)
|
button.SetImage(img)
|
||||||
button.SetImagePosition(gtk.POS_TOP)
|
button.SetImagePosition(gtk.POS_TOP)
|
||||||
name := entry.NameLoc
|
name := entry.NameLoc
|
||||||
@@ -347,7 +357,7 @@ func searchUserDir(dir string) {
|
|||||||
ignore = userDirsMap[dir]
|
ignore = userDirsMap[dir]
|
||||||
filepath.WalkDir(userDirsMap[dir], walk)
|
filepath.WalkDir(userDirsMap[dir], walk)
|
||||||
|
|
||||||
if fileSearchResults != nil && len(fileSearchResults) > 0 {
|
if len(fileSearchResults) > 0 {
|
||||||
btn := setUpUserDirButton(fmt.Sprintf("folder-%s", dir), "", dir, userDirsMap)
|
btn := setUpUserDirButton(fmt.Sprintf("folder-%s", dir), "", dir, userDirsMap)
|
||||||
fileSearchResultFlowBox.Add(btn)
|
fileSearchResultFlowBox.Add(btn)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user