From ec0b64f5f588a2e08c3e6a68dbe980bb74c1c137 Mon Sep 17 00:00:00 2001 From: Greg Date: Sat, 29 Aug 2020 19:52:51 -0400 Subject: [PATCH] Migrating to new Gio version (non-working version). --- PgpConnect.jar | Bin 6822 -> 8214 bytes PgpConnect.java | 18 ++- cmd/passgo-gui/impl_android.go | 16 ++- cmd/passgo-gui/impl_darwin.go | 20 ++- cmd/passgo-gui/impl_others.go | 10 ++ cmd/passgo-gui/main.go | 256 +++++++++++++++++---------------- cmd/passgo-gui/ui.go | 55 +++---- go.mod | 5 +- go.sum | 9 ++ impl_android.go | 16 ++- jni_android.c | 20 ++- jni_android.go | 2 +- jni_android.h | 1 + 13 files changed, 249 insertions(+), 179 deletions(-) create mode 100644 cmd/passgo-gui/impl_others.go diff --git a/PgpConnect.jar b/PgpConnect.jar index 49b2af49ac24ee86d530c7e89a7e517057513241..f41371c29f2461217651d2060d4052acd543d112 100644 GIT binary patch delta 6766 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 diff --git a/PgpConnect.java b/PgpConnect.java index b7aad63..552be58 100644 --- a/PgpConnect.java +++ b/PgpConnect.java @@ -29,6 +29,8 @@ import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.Manifest; import android.content.pm.PackageManager; +import android.content.Context; +import android.view.View; public class PgpConnect extends Fragment { Context ctx; @@ -37,8 +39,19 @@ public class PgpConnect extends Fragment { OpenPgpServiceConnection mServiceConnection; final int PERMISSIONS_REQUEST = 1; - public PgpConnect() { + public PgpConnect(View view) { Log.d("gio", "PgpConnect()"); + this.ctx = view.getContext(); + this.handler = new Handler(this.ctx.getMainLooper()); + PgpConnect inst = this; + handler.post(new Runnable() { + public void run() { + Activity act = (Activity)ctx; + FragmentTransaction ft = act.getFragmentManager().beginTransaction(); + ft.add(inst, "PgpConnect"); + ft.commitNow(); + } + }); } @Override public void onAttach(Context ctx) { @@ -47,14 +60,13 @@ public class PgpConnect extends Fragment { if (ctx instanceof Activity) { Log.d("gio", "It's an Activity!"); } - this.ctx = ctx; - this.handler = new Handler(ctx.getMainLooper()); mServiceConnection = new OpenPgpServiceConnection(ctx, "org.sufficientlysecure.keychain"); mServiceConnection.bindToService(); cb = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE); if (ctx.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ctx.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST); } + System.loadLibrary("gio"); installComplete(this); } diff --git a/cmd/passgo-gui/impl_android.go b/cmd/passgo-gui/impl_android.go index eedeeeb..43f7ac3 100644 --- a/cmd/passgo-gui/impl_android.go +++ b/cmd/passgo-gui/impl_android.go @@ -1,4 +1,4 @@ -//+build !darwin +//+build android package main @@ -7,7 +7,7 @@ import ( "git.wow.st/gmp/passgo" "gioui.org/app" - "gioui.org/font/gofont" + "gioui.org/io/event" ) var ( @@ -18,11 +18,17 @@ func init() { log(Info, "Android start") // Use a larger font on Android fontSize = 24 - gofont.Register() } -func initPgp(w *app.Window) { - passgo.InitPgp(w) +func handleEvent(e event.Event) { + switch e := e.(type) { + case app.ViewEvent: + initPgp(e.View) + } +} + +func initPgp(view uintptr) { + passgo.InitPgp(view) } func getConfDir() (string, error) { diff --git a/cmd/passgo-gui/impl_darwin.go b/cmd/passgo-gui/impl_darwin.go index 0427c79..a3770b1 100644 --- a/cmd/passgo-gui/impl_darwin.go +++ b/cmd/passgo-gui/impl_darwin.go @@ -7,9 +7,6 @@ import ( "os/user" "path" - "gioui.org/app" - "gioui.org/font" - "gioui.org/font/gofont" "gioui.org/font/opentype" "gioui.org/text" ) @@ -30,24 +27,23 @@ func setFont() error { log(Info, "Cannot parse font collection") return err } - face, err := fnts.Font(0) + fnt, err := fnts.Font(0) + if err != nil { + log(Info, "Cannot get font from collection") + return err + } + collection = append(collection, text.FontFace{Font: text.Font{}, Face: fnt}) if err != nil { log(Info, "Cannot access font from font collection") return err } - font.Register(text.Font{}, face) + //font.Register(text.Font{}, face) return nil } func init() { fontSize = 16 - err := setFont() - if err != nil { - gofont.Register() - } -} - -func initPgp(w *app.Window) { + setFont() } func getConfDir() (string, error) { diff --git a/cmd/passgo-gui/impl_others.go b/cmd/passgo-gui/impl_others.go new file mode 100644 index 0000000..523768b --- /dev/null +++ b/cmd/passgo-gui/impl_others.go @@ -0,0 +1,10 @@ +//+build !android + +package main + +import ( + "gioui.org/io/event" +) + +func handleEvent(e event.Event) { +} diff --git a/cmd/passgo-gui/main.go b/cmd/passgo-gui/main.go index 2cb15e6..b90b5ed 100644 --- a/cmd/passgo-gui/main.go +++ b/cmd/passgo-gui/main.go @@ -15,16 +15,16 @@ import ( "time" "gioui.org/app" + "gioui.org/font/gofont" "gioui.org/io/key" "gioui.org/io/system" "gioui.org/layout" + "gioui.org/op" "gioui.org/text" "gioui.org/unit" "gioui.org/widget" "gioui.org/widget/material" - //"gioui.org/font/gofont" - "github.com/fsnotify/fsnotify" "gopkg.in/yaml.v2" @@ -32,6 +32,11 @@ import ( "git.wow.st/gmp/rand" ) +type ( + D = layout.Dimensions + C = layout.Context +) + type conf struct { StoreDir string ClearDelay int @@ -113,6 +118,7 @@ func main() { var ( fontSize float32 + collection []text.FontFace confDir string Config conf l []passgo.Pass @@ -190,15 +196,16 @@ func saveConf(fds ...*os.File) { } func eventLoop() { - //gofont.Register() - th = material.NewTheme() + if collection == nil { + collection = gofont.Collection() + } + + var ops op.Ops + th = material.NewTheme(collection) th.TextSize = unit.Sp(fontSize) w := app.NewWindow( app.Size(unit.Dp(250), unit.Dp(500)), app.Title("passgo")) - initPgp(w) - gtx := layout.NewContext(w.Queue()) - //time.Sleep(time.Second/5) var margincs layout.Constraints @@ -207,7 +214,7 @@ func eventLoop() { sysinset := &layout.Inset{} margin := layout.UniformInset(unit.Dp(10)) - title := th.Body1("passgo") + title := material.Body1(th, "passgo") dotsBtn := &Button{ Size: unit.Sp(fontSize), Label: "\xe2\x8b\xae", @@ -289,7 +296,7 @@ func eventLoop() { Background: gray, } - storeDirLabel := th.Label(unit.Sp(fontSize), "Store directory") + storeDirLabel := material.Label(th, unit.Sp(fontSize), "Store directory") storeDirEd := &widget.Editor{ SingleLine: true} storeDirEd.SetText(store.Dir) saveBtn := &Button{ @@ -306,7 +313,7 @@ func eventLoop() { Color: black, Background: gray, } - confirmLabel := th.Label(unit.Sp(fontSize), "Password exists. Overwrite?") + confirmLabel := material.Label(th, unit.Sp(fontSize), "Password exists. Overwrite?") yesBtn := &Button{ Size: unit.Sp(fontSize), Label: "yes", @@ -315,7 +322,7 @@ func eventLoop() { Background: gray, } - promptLabel := th.Label(unit.Sp(fontSize), "passphrase") + promptLabel := material.Label(th, unit.Sp(fontSize), "passphrase") promptEd := &widget.Editor{ SingleLine: true, Submit: true } okBtn := &Button{ Size: unit.Sp(fontSize), @@ -332,20 +339,20 @@ func eventLoop() { Background: gray, } - insertLabel := th.Label(unit.Sp(fontSize), "Insert") - passnameLabel := th.Label(unit.Sp(fontSize), "password name:") + insertLabel := material.Label(th, unit.Sp(fontSize), "Insert") + passnameLabel := material.Label(th, unit.Sp(fontSize), "password name:") passnameEd := &widget.Editor{ SingleLine: true } - passvalLabel := th.Label(unit.Sp(fontSize), "password value:") + passvalLabel := material.Label(th, unit.Sp(fontSize), "password value:") passvalEd := &widget.Editor{ SingleLine: true, Submit: true } - noidLabel := th.Label(unit.Sp(fontSize), noidLabelText) - idLabel := th.Label(unit.Sp(fontSize), "Select ID") + noidLabel := material.Label(th, unit.Sp(fontSize), noidLabelText) + idLabel := material.Label(th, unit.Sp(fontSize), "Select ID") anim := &time.Ticker{} animating := false animOn := func() { log(Info, "animOn()") - anim = time.NewTicker(time.Second / 30) + anim = time.NewTicker(time.Second / 90) animating = true w.Invalidate() } @@ -355,7 +362,7 @@ func eventLoop() { animating = false } - var listPage, idPage, insertPage, confirmPage, confPage, promptPage, page func() + var listPage, idPage, insertPage, confirmPage, confPage, promptPage, page func(C) D _ = idPage prompt := func() []byte { @@ -365,13 +372,14 @@ func eventLoop() { return <-passch } - listPage = func() { + listPage = func(gtx C) D { // timing variables used for animation fade1a, fade1b := 1.5, 2.0 start2 := float64(Config.ClearDelay) fade2a, end := start2+1.5, start2+2.0 - c2 := layout.Flexed(1.0, func() { + c2 := layout.Flexed(1.0, func(gtx C) D { + var ret D mux.Lock() if lst.Dragging() { key.HideInputOp{}.Add(gtx.Ops) @@ -389,10 +397,10 @@ func eventLoop() { w.Invalidate() page = idPage default: - lst.Layout(gtx, len(passBtns), func(i int) { + ret = lst.Layout(gtx, len(passBtns), func(gtx C, i int) D { btn := passBtns[i] - gtx.Constraints.Width.Min = gtx.Constraints.Width.Max - btn.Layout(gtx) + gtx.Constraints.Min.X = gtx.Constraints.Max.X + ret := btn.Layout(gtx) if btn.Clicked() { log(Info, "Clicked ", btn.Label) // don't block UI thread on decryption attempt @@ -421,11 +429,13 @@ func eventLoop() { } }(pathnames[i]) } + return ret }) } mux.Unlock() + return ret }) - flex.Layout(gtx, c1, c2) + ret := flex.Layout(gtx, c1, c2) x := time.Since(overlayStart).Seconds() if x >= fade1b && x < start2 && animating { animOff() @@ -463,10 +473,9 @@ func eventLoop() { overlay.Background = darkgray } gtx.Constraints = margincs - al := layout.Align(layout.SE) - al.Layout(gtx, func() { - gtx.Constraints.Width.Min = gtx.Constraints.Width.Max - overlay.Layout(gtx) + layout.SE.Layout(gtx, func(gtx C) D { + gtx.Constraints.Min.X = gtx.Constraints.Max.X + return overlay.Layout(gtx) }) } if x > start2 && x < fade2a { @@ -475,6 +484,7 @@ func eventLoop() { if animating && x > end { animOff() } + return ret } updateBtn := &Button{ @@ -493,12 +503,12 @@ func eventLoop() { Background: gray, } - idPage = func() { + idPage = func(gtx C) D { if !animating { animOn() } - c2 := layout.Rigid(func() { - idLabel.Layout(gtx) + c2 := layout.Rigid(func(gtx C) D { + return idLabel.Layout(gtx) }) var c3 layout.FlexChild var c4 layout.FlexChild @@ -506,17 +516,17 @@ func eventLoop() { var c6 layout.FlexChild var c7 layout.FlexChild if len(idBtns) == 0 { - c3 = layout.Rigid(func() { - updateBtn.Layout(gtx) + c3 = layout.Rigid(func(gtx C) D { + return updateBtn.Layout(gtx) }) if updateBtn.Clicked() { updateIdBtns() w.Invalidate() } - c4 = layout.Rigid(func() { - th.Editor("id").Layout(gtx, idEd) + c4 = layout.Rigid(func(gtx C) D { + return material.Editor(th, idEd, "id").Layout(gtx) }) - for _, e := range idEd.Events(gtx) { + for _, e := range idEd.Events() { switch e.(type) { case widget.SubmitEvent: log(Info, "Submit") @@ -524,27 +534,28 @@ func eventLoop() { page = listPage } } - c5 = layout.Rigid(func() { - idSubmitBtn.Layout(gtx) + c5 = layout.Rigid(func(gtx C) D { + return idSubmitBtn.Layout(gtx) }) if idSubmitBtn.Clicked() { store.Id = idEd.Text() page = listPage } - c6 = layout.Rigid(func() { - noidLabel.Layout(gtx) + c6 = layout.Rigid(func(gtx C) D { + return noidLabel.Layout(gtx) }) } else { - c3 = layout.Rigid(func() { }) - c4 = layout.Rigid(func() { }) - c5 = layout.Rigid(func() { }) - c6 = layout.Rigid(func() { }) + c3 = layout.Rigid(func(gtx C) D { return D{} }) + c4 = layout.Rigid(func(gtx C) D { return D{} }) + c5 = layout.Rigid(func(gtx C) D { return D{} }) + c6 = layout.Rigid(func(gtx C) D { return D{} }) } - c7 = layout.Rigid(func() { + c7 = layout.Rigid(func(gtx C) D { + var ret D if len(idBtns) > 0 { // still zero after update for i := 0; i < len(idBtns); i++ { - lst.Layout(gtx, len(idBtns), func(i int) { - idBtns[i].Layout(gtx) + ret = lst.Layout(gtx, len(idBtns), func(gtx C, i int) D { + return idBtns[i].Layout(gtx) }) } for _, btn := range idBtns { @@ -557,8 +568,9 @@ func eventLoop() { } } } + return ret }) - flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7) + return flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7) } var insName, insValue string @@ -596,41 +608,40 @@ func eventLoop() { passvalEd.SetText(string(pw)) } - insertPage = func() { - c2 := layout.Rigid(func() { insertLabel.Layout(gtx) }) - c3 := layout.Rigid(func() { passnameLabel.Layout(gtx) }) - c4 := layout.Rigid(func() { th.Editor("name").Layout(gtx, passnameEd) }) - c5 := layout.Rigid(func() { passvalLabel.Layout(gtx) }) - c6 := layout.Rigid(func() { th.Editor("password").Layout(gtx, passvalEd) }) + insertPage = func(gtx C) D { + c2 := layout.Rigid(func(gtx C) D { return insertLabel.Layout(gtx) }) + c3 := layout.Rigid(func(gtx C) D { return passnameLabel.Layout(gtx) }) + c4 := layout.Rigid(func(gtx C) D { return material.Editor(th, passnameEd, "name").Layout(gtx) }) + c5 := layout.Rigid(func(gtx C) D { return passvalLabel.Layout(gtx) }) + c6 := layout.Rigid(func(gtx C) D { return material.Editor(th, passvalEd, "password").Layout(gtx) }) btnflx := &layout.Flex{Axis: layout.Horizontal} - al := layout.Align(layout.E) - c7 := layout.Rigid(func() { - bc1 := layout.Rigid(func() { lBtn.Layout(gtx) }) - bc2 := layout.Rigid(func() { - gtx.Constraints.Width.Min = 60 - th.Editor("len").Layout(gtx, lenEd) + c7 := layout.Rigid(func(gtx C) D { + bc1 := layout.Rigid(func(gtx C) D { return lBtn.Layout(gtx) }) + bc2 := layout.Rigid(func(gtx C) D { + gtx.Constraints.Min.X = 60 + return material.Editor(th, lenEd, "len").Layout(gtx) }) - bc3 := layout.Rigid(func() { rBtn.Layout(gtx) }) - bc4 := layout.Rigid(func() { symBtn.Layout(gtx) }) - bc5 := layout.Rigid(func() { numBtn.Layout(gtx) }) - bc6 := layout.Rigid(func() { genBtn.Layout(gtx) }) + bc3 := layout.Rigid(func(gtx C) D { return rBtn.Layout(gtx) }) + bc4 := layout.Rigid(func(gtx C) D { return symBtn.Layout(gtx) }) + bc5 := layout.Rigid(func(gtx C) D { return numBtn.Layout(gtx) }) + bc6 := layout.Rigid(func(gtx C) D { return genBtn.Layout(gtx) }) - al.Layout(gtx, func() { - btnflx.Layout(gtx, bc1, bc2, bc3, bc4, bc5, bc6) + return layout.E.Layout(gtx, func(gtx C) D { + return btnflx.Layout(gtx, bc1, bc2, bc3, bc4, bc5, bc6) }) }) - c8 := layout.Rigid(func() { - bc1 := layout.Rigid(func() { backBtn.Layout(gtx) }) - bc2 := layout.Rigid(func() { saveBtn.Layout(gtx) }) - al.Layout(gtx, func() { - btnflx.Layout(gtx, bc1, bc2) + c8 := layout.Rigid(func(gtx C) D { + bc1 := layout.Rigid(func(gtx C) D { return backBtn.Layout(gtx) }) + bc2 := layout.Rigid(func(gtx C) D { return saveBtn.Layout(gtx) }) + return layout.E.Layout(gtx, func(gtx C) D { + return btnflx.Layout(gtx, bc1, bc2) }) }) - flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7, c8) + ret := flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7, c8) if lBtn.Clicked() { l, _ := strconv.Atoi(lenEd.Text()) @@ -673,7 +684,7 @@ func eventLoop() { log(Info, "Password exists") page = confirmPage w.Invalidate() - return + return ret } } //Do not block the UI thread. @@ -684,23 +695,23 @@ func eventLoop() { } }() } + return ret } - confirmPage = func() { - c2 := layout.Rigid(func() { - confirmLabel.Layout(gtx) + confirmPage = func(gtx C) D { + c2 := layout.Rigid(func(gtx C) D { + return confirmLabel.Layout(gtx) }) - al := layout.Align(layout.E) btnflx := &layout.Flex{Axis: layout.Horizontal} - c3 := layout.Rigid(func() { - bc1 := layout.Rigid(func() { backBtn.Layout(gtx) }) - bc2 := layout.Rigid(func() { yesBtn.Layout(gtx) }) + c3 := layout.Rigid(func(gtx C) D { + bc1 := layout.Rigid(func(gtx C) D { return backBtn.Layout(gtx) }) + bc2 := layout.Rigid(func(gtx C) D { return yesBtn.Layout(gtx) }) - al.Layout(gtx, func() { - btnflx.Layout(gtx, bc1, bc2) + return layout.E.Layout(gtx, func(gtx C) D { + return btnflx.Layout(gtx, bc1, bc2) }) }) - flex.Layout(gtx, c1, c2, c3) + ret := flex.Layout(gtx, c1, c2, c3) if backBtn.Clicked() { w.Invalidate() @@ -716,26 +727,26 @@ func eventLoop() { } }() } + return ret } - confPage = func() { - c2 := layout.Rigid(func() { storeDirLabel.Layout(gtx) }) - c3 := layout.Rigid(func() { th.Editor("directory").Layout(gtx, storeDirEd) }) + confPage = func(gtx C) D { + c2 := layout.Rigid(func(gtx C) D { return storeDirLabel.Layout(gtx) }) + c3 := layout.Rigid(func(gtx C) D { return material.Editor(th, storeDirEd, "directory").Layout(gtx) }) - al := layout.Align(layout.E) - c4 := layout.Rigid(func() { + c4 := layout.Rigid(func(gtx C) D { btnflx := &layout.Flex{Axis: layout.Horizontal} - bc1 := layout.Rigid(func() { - backBtn.Layout(gtx) + bc1 := layout.Rigid(func(gtx C) D { + return backBtn.Layout(gtx) }) - bc2 := layout.Rigid(func() { - saveBtn.Layout(gtx) + bc2 := layout.Rigid(func(gtx C) D { + return saveBtn.Layout(gtx) }) - al.Layout(gtx, func() { - btnflx.Layout(gtx, bc1, bc2) + return layout.E.Layout(gtx, func(gtx C) D { + return btnflx.Layout(gtx, bc1, bc2) }) }) - flex.Layout(gtx, c1, c2, c3, c4) + ret := flex.Layout(gtx, c1, c2, c3, c4) if backBtn.Clicked() { log(Info, "Back") @@ -757,33 +768,33 @@ func eventLoop() { w.Invalidate() page = listPage } + return ret } - promptPage = func() { + promptPage = func(gtx C) D { submit := false - for _, e := range promptEd.Events(gtx) { + for _, e := range promptEd.Events() { switch e.(type) { case widget.SubmitEvent: log(Info, "Submit") submit = true } } - c2 := layout.Rigid(func() { promptLabel.Layout(gtx) }) - c3 := layout.Rigid(func() { th.Editor("password").Layout(gtx, promptEd) }) - c4 := layout.Rigid(func() { - al := layout.Align(layout.E) + c2 := layout.Rigid(func(gtx C) D { return promptLabel.Layout(gtx) }) + c3 := layout.Rigid(func(gtx C) D { return material.Editor(th, promptEd, "password").Layout(gtx) }) + c4 := layout.Rigid(func(gtx C) D { btnflx := &layout.Flex{Axis: layout.Horizontal} - bc1 := layout.Rigid(func() { - backBtn.Layout(gtx) + bc1 := layout.Rigid(func(gtx C) D { + return backBtn.Layout(gtx) }) - bc2 := layout.Rigid(func() { - okBtn.Layout(gtx) + bc2 := layout.Rigid(func(gtx C) D { + return okBtn.Layout(gtx) }) - al.Layout(gtx, func() { - btnflx.Layout(gtx, bc1, bc2) + return layout.E.Layout(gtx, func(gtx C) D { + return btnflx.Layout(gtx, bc1, bc2) }) }) - flex.Layout(gtx, c1, c2, c3, c4) + ret := flex.Layout(gtx, c1, c2, c3, c4) if submit || okBtn.Clicked() { log(Info, "Ok") @@ -801,6 +812,7 @@ func eventLoop() { w.Invalidate() page = listPage } + return ret } page = listPage @@ -832,31 +844,31 @@ func eventLoop() { }() } case system.FrameEvent: - gtx.Reset(e.Config, e.Size) + gtx := layout.NewContext(&ops, e) sysinset.Top = e.Insets.Top sysinset.Bottom = e.Insets.Bottom sysinset.Left = e.Insets.Left sysinset.Right = e.Insets.Right - sysinset.Layout(gtx, func() { - margin.Layout(gtx, func() { + sysinset.Layout(gtx, func(gtx C) D { + return margin.Layout(gtx, func(gtx C) D { margincs = gtx.Constraints - c1 = layout.Rigid(func() { - ct2 := layout.Rigid(func() { - plusBtn.Layout(gtx) + c1 = layout.Rigid(func(gtx C) D { + ct2 := layout.Rigid(func(gtx C) D { + return plusBtn.Layout(gtx) }) - ct3 := layout.Rigid(func() { - dotsBtn.Layout(gtx) + ct3 := layout.Rigid(func(gtx C) D { + return dotsBtn.Layout(gtx) }) - ct1 := layout.Flexed(1.0, func() { - gtx.Constraints.Width.Min = gtx.Constraints.Width.Max - title.Layout(gtx) + ct1 := layout.Flexed(1.0, func(gtx C) D { + gtx.Constraints.Min.X = gtx.Constraints.Max.X + return title.Layout(gtx) }) - titleflex.Layout(gtx, ct1, ct2, ct3) + return titleflex.Layout(gtx, ct1, ct2, ct3) }) - page() + return page(gtx) }) }) @@ -872,6 +884,8 @@ func eventLoop() { page = insertPage } e.Frame(gtx.Ops) + default: + handleEvent(e) } if x == 100 { x = 0 diff --git a/cmd/passgo-gui/ui.go b/cmd/passgo-gui/ui.go index 520e4d2..2f0f60d 100644 --- a/cmd/passgo-gui/ui.go +++ b/cmd/passgo-gui/ui.go @@ -12,6 +12,7 @@ import ( "gioui.org/op/paint" "gioui.org/text" "gioui.org/unit" + "gioui.org/widget/material" ) var ( @@ -30,23 +31,24 @@ type Overlay struct { Alignment text.Alignment } -func (b *Overlay) Layout(gtx *layout.Context) { +func (b *Overlay) Layout(gtx C) D { ins := layout.UniformInset(unit.Dp(1)) - ins.Layout(gtx, func() { + return ins.Layout(gtx, func(gtx C) D { st := layout.Stack{} - c2 := layout.Stacked(func() { - l := th.Label(b.Size, b.Text) + c2 := layout.Stacked(func(gtx C) D { + l := material.Label(th, b.Size, b.Text) ins := layout.UniformInset(unit.Dp(4)) l.Color = b.Color - ins.Layout(gtx, func() { - l.Layout(gtx) + ret := ins.Layout(gtx, func(gtx C) D { + return l.Layout(gtx) }) - pointer.Rect(image.Rect(0, 0, gtx.Dimensions.Size.X, gtx.Dimensions.Size.Y)).Add(gtx.Ops) + pointer.Rect(image.Rect(0, 0, ret.Size.X, ret.Size.Y)).Add(gtx.Ops) + return ret }) - c1 := layout.Expanded(func() { - layoutRRect(b.Background, gtx) + c1 := layout.Expanded(func(gtx C) D { + return layoutRRect(b.Background, gtx) }) - st.Layout(gtx, c1, c2) + return st.Layout(gtx, c1, c2) }) } @@ -66,23 +68,23 @@ type Button struct { clicked bool } -func layoutRRect(col color.RGBA, gtx *layout.Context) { +func layoutRRect(col color.RGBA, gtx C) D { r := float32(gtx.Px(unit.Dp(4))) - sz := image.Point{X: gtx.Constraints.Width.Min, Y: gtx.Constraints.Height.Min} + sz := image.Point{X: gtx.Constraints.Min.X, Y: gtx.Constraints.Min.Y} w, h := float32(sz.X), float32(sz.Y) rect := f32.Rectangle{ f32.Point{0, 0}, f32.Point{w, h}, } //clip.RoundRect(gtx.Ops, rect, r, r, r, r) - clip.Rect{Rect: rect, NE: r, NW: r, SE: r, SW: r}.Op(gtx.Ops).Add(gtx.Ops) + clip.RRect{Rect: rect, NE: r, NW: r, SE: r, SW: r}.Add(gtx.Ops) paint.ColorOp{Color: col}.Add(gtx.Ops) paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: w, Y: h}}}.Add(gtx.Ops) - gtx.Dimensions = layout.Dimensions{Size: sz} + return layout.Dimensions{Size: sz} } -func (b *Button) Layout(gtx *layout.Context) { - mwidth := gtx.Constraints.Width.Min +func (b *Button) Layout(gtx C) D { + mwidth := gtx.Constraints.Min.X b.clicked = false for _, ev := range b.Click.Events(gtx) { if ev.Type == gesture.TypeClick { @@ -90,23 +92,24 @@ func (b *Button) Layout(gtx *layout.Context) { } } ins := layout.UniformInset(unit.Dp(1)) - ins.Layout(gtx, func() { + return ins.Layout(gtx, func(gtx C) D { st := layout.Stack{} - c2 := layout.Stacked(func() { - l := th.Label(b.Size, b.Label) + c2 := layout.Stacked(func(gtx C) D { + l := material.Label(th, b.Size, b.Label) ins := layout.UniformInset(unit.Dp(4)) //paint.ColorOp{Color: b.Color}.Add(ops) - ins.Layout(gtx, func() { - l.Layout(gtx) + ret := ins.Layout(gtx, func(gtx C) D { + return l.Layout(gtx) }) - pointer.Rect(image.Rect(0, 0, gtx.Dimensions.Size.X, gtx.Dimensions.Size.Y)).Add(gtx.Ops) + pointer.Rect(image.Rect(0, 0, ret.Size.X, ret.Size.Y)).Add(gtx.Ops) b.Click.Add(gtx.Ops) + return ret }) - c1 := layout.Expanded(func() { - gtx.Constraints.Width.Min = mwidth - layoutRRect(b.Background, gtx) + c1 := layout.Expanded(func(gtx C) D { + gtx.Constraints.Min.X = mwidth + return layoutRRect(b.Background, gtx) }) - st.Layout(gtx, c1, c2) + return st.Layout(gtx, c1, c2) }) } diff --git a/go.mod b/go.mod index 79b8e47..549aada 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,13 @@ module git.wow.st/gmp/passgo go 1.13 require ( - gioui.org v0.0.0-20191218180754-3dd7c8121c67 + gioui.org v0.0.0-20200827132523-d57edbb49d3c git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5 + git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0 git.wow.st/gmp/rand v0.0.0-20191001220155-a81bebfaf8b0 github.com/fsnotify/fsnotify v1.4.7 github.com/jcmdev0/gpgagent v0.0.0-20180509014935-5601b32d936c golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c - golang.org/x/image v0.0.0-20190802002840-cff245a6509b + golang.org/x/image v0.0.0-20200618115811-c13761719519 gopkg.in/yaml.v2 v2.2.7 ) diff --git a/go.sum b/go.sum index a6af5d7..e2d84c7 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,13 @@ gioui.org v0.0.0-20191126175243-2ca2e5462f16 h1:p31rtmKm51xpj2QtqGNlljAyHEP1oStU gioui.org v0.0.0-20191126175243-2ca2e5462f16/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY= gioui.org v0.0.0-20191218180754-3dd7c8121c67 h1:y9md+l1thtMqJu/ulhF1Upv3pnOpGotpJDssO8X3LbY= gioui.org v0.0.0-20191218180754-3dd7c8121c67/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY= +gioui.org v0.0.0-20200827132523-d57edbb49d3c h1:TY1A2dzvxASVC+crmYfkDF8JNkd4rKaXZG2A4WboyU4= +gioui.org v0.0.0-20200827132523-d57edbb49d3c/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw= +gioui.org v0.0.0-20200829162755-829ee4559c5a h1:mciXRGzQwU0TbgCILZzl6L1nYIWU31lDGIb+8RYige8= git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5 h1:OKeTjZST+/TKvtdA258NXJH+/gIx/xwyZxKrAezNFvk= git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5/go.mod h1:NLdpaBoMQNFqncwP8OVRNWUDw1Kt9XWm3snfT7cXu24= +git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0 h1:Ynp3h+TC8k1clvf45D28VFQlmy0bPx8M/MG5bB24Vj8= +git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo= git.wow.st/gmp/rand v0.0.0-20191001220155-a81bebfaf8b0 h1:08wP00wvbDINsct1fzKV1xGGLvvtNsSb2X4CtIdpBzM= git.wow.st/gmp/rand v0.0.0-20191001220155-a81bebfaf8b0/go.mod h1:8+2Gwnrpc5yuk8Wp6cBhxvGcNLumYiPbQ7n0SQ8h29A= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -23,6 +28,8 @@ golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgn golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -33,6 +40,8 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/impl_android.go b/impl_android.go index cf8a8b8..f33fcd5 100644 --- a/impl_android.go +++ b/impl_android.go @@ -1,6 +1,6 @@ //+build android //go:generate mkdir -p classes -//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -classpath openpgp-api.jar -d classes PgpConnect.java +//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -classpath openpgp-api.jar -d classes PgpConnect.java Foo.java //go:generate jar cf PgpConnect.jar -C classes . //go:generate rm -rf classes @@ -19,13 +19,15 @@ import ( "log" "strings" "sync" + "unsafe" "gioui.org/app" _ "gioui.org/app/permission/storage" + //"git.wow.st/gmp/jni" ) var ( - h *app.Handle + jvm uintptr waitch chan struct{} //w *app.Window pgp PGP @@ -40,16 +42,18 @@ func init() { func Java_st_wow_git_passgo_PgpConnect_installComplete(env *C.JNIEnv, class C.jclass, p C.jobject) { log.Printf("InstallComplete()") pgp = PGP(C.NewGlobalRef(env, p)) - h = app.PlatformHandle() - SetJVM(h.JVM) installCompleteOnce.Do(func() { close(waitch) }) } -func InitPgp(w *app.Window) { +func InitPgp(view uintptr) { log.Printf("InitPgp()") - w.RegisterFragment("st/wow/git/passgo/PgpConnect") + jvm = app.JavaVM() + SetJVM(jvm) // why? + RunInJVM(func(env *JNIEnv) { + C.registerFragment(env, (C.jobject)(unsafe.Pointer(view))) + }) } func stopPgp() { diff --git a/jni_android.c b/jni_android.c index ecf7865..c1c63d3 100644 --- a/jni_android.c +++ b/jni_android.c @@ -1,16 +1,30 @@ -#include +//#include #include #include #include "jni_android.h" #include "_cgo_export.h" +void +registerFragment(JNIEnv *env, jobject view) { + jclass cls = (*env)->GetObjectClass(env, view); + jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;"); + jobject ctx = (*env)->CallObjectMethod(env, view, mid); + cls = (*env)->GetObjectClass(env, ctx); + mid = (*env)->GetMethodID(env, cls, "getClassLoader", "()Ljava/lang/ClassLoader;"); + jobject loader = (*env)->CallObjectMethod(env, ctx, mid); + cls = (*env)->GetObjectClass(env, loader); + mid = (*env)->GetMethodID(env, cls, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); + jstring str = (*env)->NewStringUTF(env, "st/wow/git/passgo/PgpConnect"); + cls = (*env)->CallObjectMethod(env, loader, mid, str); + mid = (*env)->GetMethodID(env, cls, "", "(Landroid/view/View;)V"); + jobject inst = (*env)->NewObject(env, cls, mid, view); +} + void GetId(JNIEnv* env, jobject p, int chint) { jclass cls = (*env)->GetObjectClass(env, p); - printf("GetId(): cls = %p", cls); jmethodID mid = (*env)->GetMethodID(env, cls, "GetId", "(I)V"); - printf("GetId(): mid = %p", mid); (*env)->CallObjectMethod(env, p, mid, chint); } diff --git a/jni_android.go b/jni_android.go index 722fd33..33cffc5 100644 --- a/jni_android.go +++ b/jni_android.go @@ -1,7 +1,7 @@ package passgo /* -#cgo LDFLAGS: -landroid +#cgo LDFLAGS: -landroid -llog #include #include "jni_android.h" diff --git a/jni_android.h b/jni_android.h index c89eb22..ee5eb43 100644 --- a/jni_android.h +++ b/jni_android.h @@ -1,5 +1,6 @@ #include +void registerFragment(JNIEnv *env, jobject view); void GetId(JNIEnv* env, jobject p, int chint); void Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint); void Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint);