Skip to content

Commit

Permalink
linux: remove gotk3 dependency to improve stability
Browse files Browse the repository at this point in the history
Should address the nil pointer issues, plus improve build times.
Cleaned up go.mod a bit to drop references to packages only used by examples.

Fixes #51. Fixes #37. Closes #44.
  • Loading branch information
sqweek committed Sep 11, 2020
1 parent 43ea343 commit 8a3d98e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Asks the user for a directory.
# platform details
* OSX: uses Cocoa's NSAlert/NSSavePanel/NSOpenPanel classes
* Win32: uses MessageBox/GetOpenFileName/GetSaveFileName (via package github.com/TheTitanrain/w32)
* Linux: uses Gtk's MessageDialog/FileChooserDialog (via package github.com/mattn/go-gtk)
* Linux: uses Gtk's MessageDialog/FileChooserDialog (via cgo; requires gtk3 development packages)

# build
```
Expand Down
98 changes: 56 additions & 42 deletions dlgs_linux.go
Original file line number Diff line number Diff line change
@@ -1,89 +1,103 @@
package dialog

import (
"github.com/gotk3/gotk3/gtk"
)
// #cgo pkg-config: gtk+-3.0
// #include <gtk/gtk.h>
// #include <stdlib.h>
// static GtkWidget* msgdlg(GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, char *msg) {
// return gtk_message_dialog_new(parent, flags, type, buttons, "%s", msg);
// }
// static GtkWidget* filedlg(char *title, GtkWindow *parent, GtkFileChooserAction action, char* acceptText) {
// return gtk_file_chooser_dialog_new(title, parent, action, "Cancel", GTK_RESPONSE_CANCEL, acceptText, GTK_RESPONSE_ACCEPT, NULL);
// }
import "C"
import "unsafe"

func init() {
gtk.Init(nil)
C.gtk_init(nil, nil)
}

func closeDialog(dlg *gtk.Dialog) {
dlg.Destroy()
func closeDialog(dlg *C.GtkWidget) {
C.gtk_widget_destroy(dlg)
/* The Destroy call itself isn't enough to remove the dialog from the screen; apparently
** that happens once the GTK main loop processes some further events. But if we're
** in a non-GTK app the main loop isn't running, so we empty the event queue before
** returning from the dialog functions.
** Not sure how this interacts with an actual GTK app... */
for gtk.EventsPending() {
gtk.MainIteration()
for C.gtk_events_pending() != 0 {
C.gtk_main_iteration()
}
}

func runMsgDlg(defaultTitle string, flags C.GtkDialogFlags, msgtype C.GtkMessageType, buttons C.GtkButtonsType, b *MsgBuilder) C.gint {
cmsg := C.CString(b.Msg)
defer C.free(unsafe.Pointer(cmsg))
dlg := C.msgdlg(nil, flags, msgtype, buttons, cmsg)
ctitle := C.CString(firstOf(b.Dlg.Title, defaultTitle))
defer C.free(unsafe.Pointer(ctitle))
C.gtk_window_set_title((*C.GtkWindow)(unsafe.Pointer(dlg)), ctitle)
defer closeDialog(dlg)
return C.gtk_dialog_run((*C.GtkDialog)(unsafe.Pointer(dlg)))
}

func (b *MsgBuilder) yesNo() bool {
dlg := gtk.MessageDialogNew(nil, 0, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, "%s", b.Msg)
dlg.SetTitle(firstOf(b.Dlg.Title, "Confirm?"))
defer closeDialog(&dlg.Dialog)
return dlg.Run() == gtk.RESPONSE_YES
return runMsgDlg("Confirm?", 0, C.GTK_MESSAGE_QUESTION, C.GTK_BUTTONS_YES_NO, b) == C.GTK_RESPONSE_YES
}

func (b *MsgBuilder) info() {
dlg := gtk.MessageDialogNew(nil, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "%s", b.Msg)
dlg.SetTitle(firstOf(b.Dlg.Title, "Information"))
defer closeDialog(&dlg.Dialog)
dlg.Run()
runMsgDlg("Information", 0, C.GTK_MESSAGE_INFO, C.GTK_BUTTONS_OK, b)
}

func (b *MsgBuilder) error() {
dlg := gtk.MessageDialogNew(nil, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "%s", b.Msg)
dlg.SetTitle(firstOf(b.Dlg.Title, "Error"))
defer closeDialog(&dlg.Dialog)
dlg.Run()
runMsgDlg("Error", 0, C.GTK_MESSAGE_ERROR, C.GTK_BUTTONS_OK, b)
}

func (b *FileBuilder) load() (string, error) {
return chooseFile("Open File", "Open", gtk.FILE_CHOOSER_ACTION_OPEN, b)
return chooseFile("Open File", "Open", C.GTK_FILE_CHOOSER_ACTION_OPEN, b)
}

func (b *FileBuilder) save() (string, error) {
f, err := chooseFile("Save File", "Save", gtk.FILE_CHOOSER_ACTION_SAVE, b)
f, err := chooseFile("Save File", "Save", C.GTK_FILE_CHOOSER_ACTION_SAVE, b)
if err != nil {
return "", err
}
return f, nil
}

func chooseFile(title string, buttonText string, action gtk.FileChooserAction, b *FileBuilder) (string, error) {
dlg, err := gtk.FileChooserDialogNewWith2Buttons(firstOf(b.Dlg.Title, title),
nil, action, "Cancel", gtk.RESPONSE_CANCEL, buttonText, gtk.RESPONSE_ACCEPT)
if err != nil {
return "", err
}
func chooseFile(title string, buttonText string, action C.GtkFileChooserAction, b *FileBuilder) (string, error) {
ctitle := C.CString(title)
defer C.free(unsafe.Pointer(ctitle))
cbuttonText := C.CString(buttonText)
defer C.free(unsafe.Pointer(cbuttonText))
dlg := C.filedlg(ctitle, nil, action, cbuttonText)
fdlg := (*C.GtkFileChooser)(unsafe.Pointer(dlg))

for _, filt := range b.Filters {
filter, err := gtk.FileFilterNew()
if err != nil {
return "", err
}
filter := C.gtk_file_filter_new()
cdesc := C.CString(filt.Desc)
defer C.free(unsafe.Pointer(cdesc))
C.gtk_file_filter_set_name(filter, cdesc)

filter.SetName(filt.Desc)
for _, ext := range filt.Extensions {
filter.AddPattern("*." + ext)
cpattern := C.CString("*." + ext)
defer C.free(unsafe.Pointer(cpattern))
C.gtk_file_filter_add_pattern(filter, cpattern)
}
dlg.AddFilter(filter)
C.gtk_file_chooser_add_filter(fdlg, filter)
}
if b.StartDir != "" {
dlg.SetCurrentFolder(b.StartDir)
cdir := C.CString(b.StartDir)
defer C.free(unsafe.Pointer(cdir))
C.gtk_file_chooser_set_current_folder(fdlg, cdir)
}
dlg.SetDoOverwriteConfirmation(true)
r := dlg.Run()
defer closeDialog(&dlg.Dialog)
if r == gtk.RESPONSE_ACCEPT {
return dlg.GetFilename(), nil
C.gtk_file_chooser_set_do_overwrite_confirmation(fdlg, C.TRUE)
r := C.gtk_dialog_run((*C.GtkDialog)(unsafe.Pointer(dlg)))
defer closeDialog(dlg)
if r == C.GTK_RESPONSE_ACCEPT {
return C.GoString(C.gtk_file_chooser_get_filename(fdlg)), nil
}
return "", ErrCancelled
}

func (b *DirectoryBuilder) browse() (string, error) {
return chooseFile("Open Folder", "Open", gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, &FileBuilder{Dlg: b.Dlg})
return chooseFile("Open Folder", "Open", C.GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, &FileBuilder{Dlg: b.Dlg})
}
7 changes: 0 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
module github.com/sqweek/dialog

require (
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802
github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e
github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf
github.com/mattn/go-gtk v0.0.0-20180216084204-5a311a1830ab
github.com/mattn/go-pointer v0.0.0-20171114154726-1d30dc4b6f28
github.com/skelterjohn/go.wde v0.0.0-20180104102407-a0324cbf3ffe
)
8 changes: 0 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
github.com/AllenDang/w32 v0.0.0-20170622012957-9a4ee0f7d224/go.mod h1:1rHKulT5eD2DzdKxDXUZRKtBfkTzLmTL42ZmEmOfyrs=
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf h1:FPsprx82rdrX2jiKyS17BH6IrTmUBYqZa/CXT4uvb+I=
github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I=
github.com/mattn/go-gtk v0.0.0-20180216084204-5a311a1830ab/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
github.com/mattn/go-pointer v0.0.0-20171114154726-1d30dc4b6f28/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/skelterjohn/go.wde v0.0.0-20180104102407-a0324cbf3ffe/go.mod h1:zXxNsJHeUYIqpg890APBNEn9GoCbA4Cdnvuv3mx4fBk=

0 comments on commit 8a3d98e

Please sign in to comment.