Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d050598086 | ||
|
|
42ddd815f4 | ||
|
|
8b1dfb4421 | ||
|
|
d572c1125d | ||
|
|
6b055bb48a | ||
|
|
165b925da2 | ||
|
|
058f8684aa | ||
|
|
f4b51b0706 | ||
|
|
b781f58097 | ||
|
|
68137935a9 |
@@ -15,9 +15,9 @@ You may pin applications by right-clicking them. Pinned items will appear above
|
|||||||
a pinned item to unpin it. The pinned items cache is shared with [nwg-menu](https://github.com/nwg-piotr/nwg-menu)
|
a pinned item to unpin it. The pinned items cache is shared with [nwg-menu](https://github.com/nwg-piotr/nwg-menu)
|
||||||
and `nwggrid`.
|
and `nwggrid`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[more screenshots](https://scrot.cloud/album/nwg-drawer.Bogd) | [see on YouTube](https://youtu.be/iIgxJQhCQf0)
|
[see on YouTube](https://youtu.be/iIgxJQhCQf0)
|
||||||
|
|
||||||
[](https://repology.org/project/nwg-drawer/versions)
|
[](https://repology.org/project/nwg-drawer/versions)
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ Edit `~/.config/nwg-drawer/drawer.css` to your taste.
|
|||||||
|
|
||||||
When the search phrase is at least 3 characters long, your XDG user directories are being searched.
|
When the search phrase is at least 3 characters long, your XDG user directories are being searched.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Use the **left mouse button** to open a file with the `xdg-open` command. As configuring file associations for it is
|
Use the **left mouse button** to open a file with the `xdg-open` command. As configuring file associations for it is
|
||||||
PITA, you may override them, by creating the `~/.config/nwg-panel/preferred-apps.json` file with your own definitions.
|
PITA, you may override them, by creating the `~/.config/nwg-panel/preferred-apps.json` file with your own definitions.
|
||||||
|
|||||||
61
main.go
61
main.go
@@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/gotk3/gotk3/gtk"
|
"github.com/gotk3/gotk3/gtk"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "0.2.7"
|
const version = "0.2.8"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
appDirs []string
|
appDirs []string
|
||||||
@@ -100,9 +100,8 @@ var (
|
|||||||
statusLabel *gtk.Label
|
statusLabel *gtk.Label
|
||||||
status string
|
status string
|
||||||
ignore string
|
ignore string
|
||||||
showWindowTrigger bool
|
|
||||||
desktopTrigger bool
|
desktopTrigger bool
|
||||||
pinnedTrigger bool
|
pinnedItemsChanged chan interface{} = make(chan interface{}, 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
func defaultStringIfBlank(s, fallback string) string {
|
func defaultStringIfBlank(s, fallback string) string {
|
||||||
@@ -121,6 +120,10 @@ var targetOutput = flag.String("o", "", "name of the Output to display the drawe
|
|||||||
var displayVersion = flag.Bool("v", false, "display Version information")
|
var displayVersion = flag.Bool("v", false, "display Version information")
|
||||||
var overlay = flag.Bool("ovl", false, "use OVerLay layer")
|
var overlay = flag.Bool("ovl", false, "use OVerLay layer")
|
||||||
var iconSize = flag.Int("is", 64, "Icon Size")
|
var iconSize = flag.Int("is", 64, "Icon Size")
|
||||||
|
var marginTop = flag.Int("mt", 0, "Margin Top")
|
||||||
|
var marginLeft = flag.Int("ml", 0, "Margin Left")
|
||||||
|
var marginRight = flag.Int("mr", 0, "Margin Right")
|
||||||
|
var marginBottom = flag.Int("mb", 0, "Margin Bottom")
|
||||||
var fsColumns = flag.Uint("fscol", 2, "File Search result COLumns")
|
var fsColumns = flag.Uint("fscol", 2, "File Search result COLumns")
|
||||||
var columnsNumber = flag.Uint("c", 6, "number of Columns")
|
var columnsNumber = flag.Uint("c", 6, "number of Columns")
|
||||||
var itemSpacing = flag.Uint("spacing", 20, "icon spacing")
|
var itemSpacing = flag.Uint("spacing", 20, "icon spacing")
|
||||||
@@ -148,6 +151,7 @@ func main() {
|
|||||||
|
|
||||||
// Gentle SIGTERM handler thanks to reiki4040 https://gist.github.com/reiki4040/be3705f307d3cd136e85
|
// Gentle SIGTERM handler thanks to reiki4040 https://gist.github.com/reiki4040/be3705f307d3cd136e85
|
||||||
// v0.2: we also need to support SIGUSR from now on
|
// v0.2: we also need to support SIGUSR from now on
|
||||||
|
showWindowChannel := make(chan interface{}, 1)
|
||||||
signalChan := make(chan os.Signal, 1)
|
signalChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGUSR1)
|
signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGUSR1)
|
||||||
|
|
||||||
@@ -164,7 +168,7 @@ func main() {
|
|||||||
// let's just set e helper variable here. We'll be checking it with glib.TimeoutAdd.
|
// let's just set e helper variable here. We'll be checking it with glib.TimeoutAdd.
|
||||||
if !win.IsVisible() {
|
if !win.IsVisible() {
|
||||||
log.Debug("SIGUSR1 received, showing the window")
|
log.Debug("SIGUSR1 received, showing the window")
|
||||||
showWindowTrigger = true
|
showWindowChannel <- struct{}{}
|
||||||
} else {
|
} else {
|
||||||
log.Debug("SIGUSR1 received, hiding the window")
|
log.Debug("SIGUSR1 received, hiding the window")
|
||||||
restoreStateAndHide()
|
restoreStateAndHide()
|
||||||
@@ -343,6 +347,11 @@ func main() {
|
|||||||
layershell.SetLayer(win, layershell.LAYER_SHELL_LAYER_TOP)
|
layershell.SetLayer(win, layershell.LAYER_SHELL_LAYER_TOP)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
layershell.SetKeyboardMode(win, layershell.LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE)
|
layershell.SetKeyboardMode(win, layershell.LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,8 +501,25 @@ func main() {
|
|||||||
log.Info(fmt.Sprintf("UI created in %v ms. Thank you for your patience.", t.Sub(timeStart).Milliseconds()))
|
log.Info(fmt.Sprintf("UI created in %v ms. Thank you for your patience.", t.Sub(timeStart).Milliseconds()))
|
||||||
|
|
||||||
// Check if showing the window has been requested (SIGUSR1)
|
// Check if showing the window has been requested (SIGUSR1)
|
||||||
glib.TimeoutAdd(uint(1), func() bool {
|
go func() {
|
||||||
if showWindowTrigger && win != nil && !win.IsVisible() {
|
for {
|
||||||
|
select {
|
||||||
|
case <-showWindowChannel:
|
||||||
|
log.Debug("Showing window")
|
||||||
|
glib.TimeoutAdd(0, func() bool {
|
||||||
|
if win != nil && !win.IsVisible() {
|
||||||
|
|
||||||
|
// Refresh files before displaying the root window
|
||||||
|
// some .desktop file changed
|
||||||
|
if desktopTrigger {
|
||||||
|
log.Debug(".desktop file changed")
|
||||||
|
desktopFiles = listDesktopFiles()
|
||||||
|
status = parseDesktopFiles(desktopFiles)
|
||||||
|
appFlowBox = setUpAppsFlowBox(nil, "")
|
||||||
|
desktopTrigger = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show window and focus the search box
|
||||||
win.ShowAll()
|
win.ShowAll()
|
||||||
if fileSearchResultWrapper != nil {
|
if fileSearchResultWrapper != nil {
|
||||||
fileSearchResultWrapper.Hide()
|
fileSearchResultWrapper.Hide()
|
||||||
@@ -507,26 +533,21 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showWindowTrigger = false
|
|
||||||
|
|
||||||
// some .desktop file changed
|
return false
|
||||||
if desktopTrigger {
|
})
|
||||||
log.Debug(".desktop file changed")
|
|
||||||
desktopFiles = listDesktopFiles()
|
|
||||||
status = parseDesktopFiles(desktopFiles)
|
|
||||||
appFlowBox = setUpAppsFlowBox(nil, "")
|
|
||||||
desktopTrigger = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// pinned file changed
|
case <-pinnedItemsChanged:
|
||||||
if pinnedTrigger {
|
glib.TimeoutAdd(0, func() bool {
|
||||||
log.Debug("pinned file changed")
|
log.Debug("pinned file changed")
|
||||||
pinnedTrigger = false
|
|
||||||
pinned, _ = loadTextFile(pinnedFile)
|
pinned, _ = loadTextFile(pinnedFile)
|
||||||
pinnedFlowBox = setUpPinnedFlowBox()
|
pinnedFlowBox = setUpPinnedFlowBox()
|
||||||
}
|
|
||||||
return true
|
return false
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
go watchFiles()
|
go watchFiles()
|
||||||
|
|
||||||
|
|||||||
20
tools.go
20
tools.go
@@ -583,7 +583,15 @@ func launch(command string, terminal bool) {
|
|||||||
Setsid: true,
|
Setsid: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Start()
|
if cmd.Start() != nil {
|
||||||
|
log.Warn("Unable to launch terminal emulator!")
|
||||||
|
} else {
|
||||||
|
// Collect the exit code of the child process to prevent zombies
|
||||||
|
// if the drawer runs in resident mode
|
||||||
|
go func() {
|
||||||
|
_ = cmd.Wait()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if *resident {
|
if *resident {
|
||||||
restoreStateAndHide()
|
restoreStateAndHide()
|
||||||
@@ -609,7 +617,15 @@ func open(filePath string, xdgOpen bool) {
|
|||||||
}
|
}
|
||||||
log.Infof("Executing: %s", cmd)
|
log.Infof("Executing: %s", cmd)
|
||||||
|
|
||||||
cmd.Start()
|
if cmd.Start() != nil {
|
||||||
|
log.Warn("Unable to execute command!")
|
||||||
|
} else {
|
||||||
|
// Collect the exit code of the child process to prevent zombies
|
||||||
|
// if the drawer runs in resident mode
|
||||||
|
go func() {
|
||||||
|
_ = cmd.Wait()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if *resident {
|
if *resident {
|
||||||
restoreStateAndHide()
|
restoreStateAndHide()
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ func watchFiles() {
|
|||||||
event.Op.String() == "RENAME") {
|
event.Op.String() == "RENAME") {
|
||||||
desktopTrigger = true
|
desktopTrigger = true
|
||||||
} else if event.Name == pinnedFile {
|
} else if event.Name == pinnedFile {
|
||||||
pinnedTrigger = true
|
// TODO: This can be used to propagate information about the changed file to the
|
||||||
|
// GUI to avoid recreating everything
|
||||||
|
pinnedItemsChanged <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
case err := <-watcher.Errors:
|
case err := <-watcher.Errors:
|
||||||
|
|||||||
Reference in New Issue
Block a user