diff --git a/bin/nwg-drawer b/bin/nwg-drawer index 0354800..316803b 100755 Binary files a/bin/nwg-drawer and b/bin/nwg-drawer differ diff --git a/main.go b/main.go index 1d371e8..6b8bd68 100644 --- a/main.go +++ b/main.go @@ -19,7 +19,7 @@ import ( "github.com/gotk3/gotk3/gtk" ) -const version = "0.1.6" +const version = "0.1.7" var ( appDirs []string @@ -28,6 +28,7 @@ var ( pinned []string src glib.SourceHandle id2entry map[string]desktopEntry + preferredApps map[string]interface{} ) var categoryNames = [...]string{ @@ -188,6 +189,17 @@ func main() { status = parseDesktopFiles(desktopFiles) + // For opening files we use xdg-open. As its configuration is PITA, we may override some associations + // in the ~/.config/nwg-panel/preferred-apps.json file. + paFile := filepath.Join(configDirectory, "preferred-apps.json") + preferredApps, err = loadPreferredApps(paFile) + if err != nil { + println(fmt.Sprintf("Custom associations file %s not found or invalid", paFile)) + } else { + println(fmt.Sprintf("Found %v associations in %s", len(preferredApps), paFile)) + fmt.Println(preferredApps) + } + // USER INTERFACE gtk.Init(nil) diff --git a/tools.go b/tools.go index eb2b20e..3d53167 100644 --- a/tools.go +++ b/tools.go @@ -2,6 +2,8 @@ package main import ( "context" + "encoding/json" + "errors" "fmt" "io" "io/fs" @@ -10,6 +12,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "sort" "strings" "time" @@ -243,6 +246,25 @@ func getAppDirs() []string { return dirs } +func loadPreferredApps(path string) (map[string]interface{}, error) { + jsonFile, err := os.Open(path) + if err != nil { + return nil, err + } + defer jsonFile.Close() + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var result map[string]interface{} + json.Unmarshal([]byte(byteValue), &result) + + if len(result) == 0 { + return nil, errors.New("json invalid or empty") + } + + return result, nil +} + func listFiles(dir string) ([]fs.FileInfo, error) { files, err := ioutil.ReadDir(dir) if err == nil { @@ -622,14 +644,25 @@ func launch(command string, terminal bool) { }) } -func open(filePath string) { - cmd := exec.Command(*fileManager, filePath) +func open(filePath string, xdgOpen bool) { + var cmd *exec.Cmd + if xdgOpen { + cmd = exec.Command("xdg-open", filePath) + // Look for possible custom file association + for key, element := range preferredApps { + r, _ := regexp.Compile(key) + if r.MatchString(filePath) { + cmd = exec.Command(fmt.Sprintf("%v", element), filePath) + break + } + } + } else { + cmd = exec.Command(*fileManager, filePath) + } + fmt.Println(cmd) cmd.Start() - glib.TimeoutAdd(uint(150), func() bool { - gtk.MainQuit() - return false - }) + gtk.MainQuit() } // Returns map output name -> gdk.Monitor diff --git a/uicomponents.go b/uicomponents.go index d366a45..e4270e0 100644 --- a/uicomponents.go +++ b/uicomponents.go @@ -387,7 +387,8 @@ func searchUserDir(dir string) { } fileSearchResultFlowBox.Hide() - statusLabel.SetText(fmt.Sprintf("%v results", fileSearchResultFlowBox.GetChildren().Length())) + statusLabel.SetText(fmt.Sprintf("%v results | LMB: xdg-open | RMB: file manager", + fileSearchResultFlowBox.GetChildren().Length())) num := uint(fileSearchResultFlowBox.GetChildren().Length() / *fsColumns) fileSearchResultFlowBox.SetMinChildrenPerLine(num + 1) fileSearchResultFlowBox.SetMaxChildrenPerLine(num + 1) @@ -414,8 +415,16 @@ func setUpUserDirButton(iconName, displayName, entryName string, userDirsMap map } button.SetLabel(displayName) - button.Connect("clicked", func() { - launch(fmt.Sprintf("%s %s", *fileManager, userDirsMap[entryName]), false) + button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { + btnEvent := gdk.EventButtonNewFromEvent(e) + if btnEvent.Button() == 1 { + open(userDirsMap[entryName], true) + return true + } else if btnEvent.Button() == 3 { + open(userDirsMap[entryName], false) + return true + } + return false }) box.PackStart(button, false, true, 0) @@ -443,8 +452,16 @@ func setUpUserFileSearchResultButton(fileName, filePath string) *gtk.Box { button.SetTooltipText(tooltipText) } - button.Connect("clicked", func() { - open(filePath) + button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { + btnEvent := gdk.EventButtonNewFromEvent(e) + if btnEvent.Button() == 1 { + open(filePath, true) + return true + } else if btnEvent.Button() == 3 { + open(filePath, false) + return true + } + return false }) box.PackStart(button, false, true, 0)