diff --git a/README.md b/README.md index 3d9fe8f..aa6a576 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ $ nwg-drawer -h Usage of nwg-drawer: -c uint number of Columns (default 6) + -close + close drawer of existing instance -d Turn on Debug messages -fm string File Manager (default "thunar") @@ -86,6 +88,8 @@ Usage of nwg-drawer: Disable file search -o string name of the Output to display the drawer on (sway & Hyprland only) + -open + open drawer of existing instance -ovl use OVerLay layer -pbexit string @@ -137,6 +141,15 @@ this should be a little bit faster. Running a resident instance should speed up use of the drawer significantly. Pay attention to the fact, that you need to `pkill -f nwg-drawer` and reload the compositor to apply any new arguments! +If you want to explicitly specify commands to open and close the resident instance, which can be helpful for touchpad gestures, please use the `-open` and `-close` parameters. Similarly, some signals can also be use: pkill -USR2 nwg-drawer to open and pkill -SIGRTMIN+3 nwg-drawer to close. + +For a MacOS-style three-finger pinch: + +```text +bindgesture pinch:4:inward exec pkill -SIGUSR2 nwg-drawer +bindgesture pinch:4:outward exec pkill -SIGRTMIN+3 nwg-drawer +``` + ## Logging In case you encounter an issue, you may need debug messages. If you use the resident instance, you'll see nothing diff --git a/main.go b/main.go index f392bbf..a001ae4 100644 --- a/main.go +++ b/main.go @@ -155,6 +155,8 @@ var targetOutput = flag.String("o", "", "name of the Output to display the drawe var displayVersion = flag.Bool("v", false, "display Version information") var keyboard = flag.Bool("k", false, "set GTK layer shell Keyboard interactivity to 'on-demand' mode") var overlay = flag.Bool("ovl", false, "use OVerLay layer") +var flagDrawerOpen = flag.Bool("open", false, "open drawer of existing instance") +var flagDrawerClose = flag.Bool("close", false, "close drawer of existing instance") var gtkTheme = flag.String("g", "", "GTK theme name") var gtkIconTheme = flag.String("i", "", "GTK icon theme name") var iconSize = flag.Int("is", 64, "Icon Size") @@ -201,8 +203,10 @@ func main() { // v0.2: we also need to support SIGUSR from now on showWindowChannel := make(chan interface{}, 1) signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGUSR1) - + const ( + SIG25 = syscall.Signal(0x25) // Which is SIGRTMIN+3 on Linux, it's not used by the system + ) + signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGUSR2, SIG25) go func() { for { s := <-signalChan @@ -210,7 +214,7 @@ func main() { case syscall.SIGTERM: log.Info("SIGTERM received, bye bye") gtk.MainQuit() - case syscall.SIGUSR1: + case syscall.SIGUSR1: // toggle drawer if *resident { // As win.Show() called from inside a goroutine randomly crashes GTK, // let's just set e helper variable here. We'll be checking it with glib.TimeoutAdd. @@ -225,6 +229,23 @@ func main() { log.Info("SIGUSR1 received, and I'm not resident, bye bye") gtk.MainQuit() } + case syscall.SIGUSR2: // open drawer + if *resident { + log.Debug("SIGUSR2 received, showing the window") + showWindowChannel <- struct{}{} + } else { + log.Info("SIGUSR2 received, and I'm not resident but I'm still here, doing nothing") + } + case SIG25: // colse drawer + if *resident { + log.Debug("SIG25 received, hiding the window") + if win.IsVisible() { + restoreStateAndHide() + } + } else { + log.Info("A signal received, and I'm not resident, bye bye") + gtk.MainQuit() + } default: log.Infof("Unknown signal: %s", s.String()) } @@ -246,8 +267,17 @@ func main() { if *resident { log.Warnf("Resident instance already running (PID %v)", i) } else { - log.Infof("Showing resident instance (PID %v)", i) - err := syscall.Kill(i, syscall.SIGUSR1) + var err error + if *flagDrawerClose { + log.Infof("Closing resident instance (PID %v)", i) + err = syscall.Kill(i, SIG25) + } else if *flagDrawerOpen { + log.Infof("Showing resident instance (PID %v)", i) + err = syscall.Kill(i, syscall.SIGUSR2) + } else { + log.Infof("Togging resident instance (PID %v)", i) + err = syscall.Kill(i, syscall.SIGUSR1) + } if err != nil { return } @@ -474,7 +504,7 @@ func main() { win.Connect("key-press-event", func(_ *gtk.Window, event *gdk.Event) bool { key := &gdk.EventKey{Event: event} switch key.KeyVal() { - case gdk.KEY_downarrow, gdk.KEY_Up, gdk.KEY_Down, gdk.KEY_Left, gdk.KEY_Right, gdk.KEY_Tab, + 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 @@ -487,9 +517,9 @@ func main() { }) /* - In case someone REALLY needed to use X11 - for some stupid Zoom meeting or something, this allows - the drawer to behave properly on Openbox, and possibly somewhere else. For sure not on i3. - This feature is not really supported and will stay undocumented. + In case someone REALLY needed to use X11 - for some stupid Zoom meeting or something, this allows + the drawer to behave properly on Openbox, and possibly somewhere else. For sure not on i3. + This feature is not really supported and will stay undocumented. */ if !wayland() { log.Info("Not Wayland, oh really?")