8 Commits

Author SHA1 Message Date
Belac Darkstorm 2f8de0bed2 fix with wine 2016-09-14 09:30:06 -05:00
Belac Darkstorm 67ca030bb2 Updated README 2016-09-14 08:05:18 -05:00
Belac Darkstorm da46399ded Wine support work continued 2016-09-14 03:18:09 -05:00
Belac Darkstorm e5d0b6a9a2 First rendition of wine support (needs some work still) 2016-09-14 02:31:04 -05:00
Belac Darkstorm f4ca2115d4 Stderr output 2016-09-14 02:06:56 -05:00
Belac Darkstorm 0cc7f8f445 Updated README 2016-09-13 08:27:05 -05:00
Belac Darkstorm 767e894acd Updated README 2016-09-13 08:25:52 -05:00
Belac Darkstorm 06e2afef1d Updated README 2016-09-13 08:03:55 -05:00
4 changed files with 107 additions and 20 deletions
+5 -5
View File
@@ -1,21 +1,21 @@
# LinuxPA # LinuxPA
LinuxPA is a try to bring a PortableApps.com type launcher to Linux. LinuxPA is a try to bring a [PortableApps.com](http://portableapps.com) type launcher to Linux.
# App Detection # App Detection
LinuxPA looks in all folders in the PortableApps folder for, first, a script file (starts with the shebang (`#!`)) and, secondly, a native linux executable (starts with ELF). It will only add the first one it finds. LinuxPA looks in all folders in the PortableApps folder for, first, a script file (starts with the shebang (`#!`)) and, secondly, a native linux executable (starts with ELF). It will only add the first one it finds.
# PortableApps.com Compatability # PortableApps.com Compatibility
LinuxPA works will with the PortableApps.com launcher, as it looks for apps in the PortableApps folder and grabs the app's name and icon from where it should be in the PortableApps.com format. LinuxPA works will with the PortableApps.com launcher, as it looks for apps in the PortableApps folder and grabs the app's name and icon from where it should be in the PortableApps.com format.
# common.sh # common.sh
common.sh is found in the PortableApps/LinuxPACom folder and is executed before the app. I mainly use it to set environment variables (such as HOME). common.sh is found in the PortableApps/LinuxPACom folder and is executed before the app. I mainly use it to set environment variables (such as HOME).
# Simple App Setup # Simple App Setup
Because apps aren't natively formated in the PortableApps.com format, if LinuxPA doesn't find the AppInfo.ini or appicon_\*.png in the App/AppInfo folder of the app it looks for them in the root direcory of the app (except it looks, nor for appicon_\*.png, but appicon.png) Because apps aren't natively formated in the PortableApps.com format, if LinuxPA doesn't find the AppInfo.ini or appicon_\*.png in the App/AppInfo folder of the app it looks for them in the root directory of the app (except it looks, nor for appicon_\*.png, but appicon.png). If an AppInfo.ini file isn't found then the name of the app is grabbed from the folder name and it's category is set to other. It specifically looks for the lines starting with `Name=` and `Category=`
# AppImage Support # AppImage Support
[AppImage Website](http://appimage.org) [AppImage Website](http://appimage.org)
Right now AppImages are simply supported via the native linux executable support, but later I'm hoping to add downloading and automatic downloading support. Right now AppImages are simply supported via the native linux executable support, but later I'm hoping to add downloading and automatic updating support.
# USB mount # USB mount
Unfortunately Linux, by default, doesn't support running executables off of flash drives, requiring you to mount your drive with special mount arguments, I personally use the arguments `exec,noauto,nodev,nosuid,umask=0000` Unfortunately Linux, by default, doesn't support running executables off of flash drives, requiring you to mount your drive with special mount arguments, I personally use the arguments `exec,noauto,nodev,nosuid,umask=0000`
@@ -25,8 +25,8 @@ Photos are found [Here](https://goo.gl/photos/VtBUL6DyZTMidj5n6)
# TODO (Might be in order) # TODO (Might be in order)
1. MAKE IT BETTER 1. MAKE IT BETTER
1. Launching of .exe files via wine (wine will have to be installed on the host system, unless there is some portable wine (I may have found one))
1. Add settings menu 1. Add settings menu
1. Add updater for .AppImage files 1. Add updater for .AppImage files
1. Download .AppImage files (maybe) 1. Download .AppImage files (maybe)
1. Check if all apps are closed when it closes and ask if you want to force stop the apps. 1. Check if all apps are closed when it closes and ask if you want to force stop the apps.
1. Portable wine???
+38 -4
View File
@@ -14,6 +14,8 @@ import (
var ( var (
appMaster map[string][]prtap appMaster map[string][]prtap
cats []string cats []string
wineOnly []string
linOnly []string
conf *os.File conf *os.File
common string common string
commEnbl bool commEnbl bool
@@ -24,6 +26,7 @@ type prtap struct {
cat string cat string
ex string ex string
desc string desc string
wine bool
} }
func main() { func main() {
@@ -43,7 +46,7 @@ func main() {
appstmp, _ := pa.Readdir(-1) appstmp, _ := pa.Readdir(-1)
var folds []string var folds []string
for _, v := range appstmp { for _, v := range appstmp {
if v.IsDir() && v.Name() != "LinuxPACom" { if v.IsDir() && v.Name() != "LinuxPACom" && v.Name() != "PortableApps.com" {
folds = append(folds, v.Name()) folds = append(folds, v.Name())
} }
} }
@@ -53,11 +56,30 @@ func main() {
pat := processApp(fi) pat := processApp(fi)
if (pat != prtap{}) { if (pat != prtap{}) {
if _, ok := appMaster[pat.cat]; !ok { if _, ok := appMaster[pat.cat]; !ok {
cats = append(cats, pat.cat) if pat.wine {
wineOnly = append(wineOnly, pat.cat)
cats = append(cats, pat.cat)
} else {
linOnly = append(linOnly, pat.cat)
cats = append(cats, pat.cat)
}
} else {
if !pat.wine {
for i, v := range wineOnly {
if pat.cat == v {
wineOnly = append(wineOnly[:i], wineOnly[i+1:]...)
linOnly = append(linOnly, pat.cat)
break
}
}
}
} }
appMaster[pat.cat] = append(appMaster[pat.cat], pat) appMaster[pat.cat] = append(appMaster[pat.cat], pat)
} }
} }
sort.Strings(linOnly)
sort.Strings(wineOnly)
sort.Strings(cats)
gl.StartDriver(uiMain) gl.StartDriver(uiMain)
} }
@@ -72,13 +94,13 @@ func processApp(fi *os.File) (out prtap) {
fil, _ = os.Open(fi.Name() + "/appinfo.ini") fil, _ = os.Open(fi.Name() + "/appinfo.ini")
out.cat = getCat(fil) out.cat = getCat(fil)
} else { } else {
out.cat = "other" out.cat = "Other"
} }
if out.name == "" { if out.name == "" {
out.name = path.Base(fi.Name()) out.name = path.Base(fi.Name())
} }
if out.cat == "" { if out.cat == "" {
out.cat = "other" out.cat = "Other"
} }
//executable detection //executable detection
wd, _ := os.Getwd() wd, _ := os.Getwd()
@@ -116,6 +138,18 @@ func processApp(fi *os.File) (out prtap) {
} }
} }
} }
for _, v := range fis {
fil, err := os.Open(wd + "/" + fi.Name() + "/" + v.Name())
if err == nil {
stat, _ := fil.Stat()
if !stat.IsDir() && strings.HasSuffix(stat.Name(), "exe") {
out.wine = true
out.ex = wd + "/" + fi.Name() + "/" + v.Name()
out.name += " (Wine)"
return
}
}
}
return prtap{} return prtap{}
} }
+34 -7
View File
@@ -15,16 +15,43 @@ import (
type prtapAdap struct { type prtapAdap struct {
gxui.AdapterBase gxui.AdapterBase
apps []prtap wine bool
master []prtap
cur []prtap
} }
func (p *prtapAdap) SetApps(apps []prtap) { func (p *prtapAdap) SetApps(apps []prtap) {
p.apps = apps p.master = apps
if p.wine {
p.cur = p.master
} else {
p.cur = make([]prtap, 0)
for _, v := range p.master {
if !v.wine {
p.cur = append(p.cur, v)
}
}
}
p.DataChanged(false) p.DataChanged(false)
} }
func (p *prtapAdap) Count() int { func (p *prtapAdap) Count() int {
return len(p.apps) return len(p.cur)
}
func (p *prtapAdap) Wine(show bool) {
p.wine = show
if show {
p.cur = p.master
} else {
p.cur = make([]prtap, 0)
for _, v := range p.master {
if !v.wine {
p.cur = append(p.cur, v)
}
}
}
p.DataChanged(false)
} }
func (p *prtapAdap) Create(th gxui.Theme, index int) gxui.Control { func (p *prtapAdap) Create(th gxui.Theme, index int) gxui.Control {
@@ -32,7 +59,7 @@ func (p *prtapAdap) Create(th gxui.Theme, index int) gxui.Control {
box.SetPadding(math.CreateSpacing(2)) box.SetPadding(math.CreateSpacing(2))
box.SetDirection(gxui.LeftToRight) box.SetDirection(gxui.LeftToRight)
box.SetVerticalAlignment(gxui.AlignMiddle) box.SetVerticalAlignment(gxui.AlignMiddle)
dir := path.Dir(p.apps[index].ex) dir := path.Dir(p.cur[index].ex)
if fold, err := os.Open(dir + "/App/AppInfo"); err == nil { if fold, err := os.Open(dir + "/App/AppInfo"); err == nil {
var pics []string var pics []string
fi, _ := fold.Readdirnames(-1) fi, _ := fold.Readdirnames(-1)
@@ -76,13 +103,13 @@ func (p *prtapAdap) Create(th gxui.Theme, index int) gxui.Control {
box.AddChild(icon) box.AddChild(icon)
} }
lbl := th.CreateLabel() lbl := th.CreateLabel()
lbl.SetText(p.apps[index].name) lbl.SetText(p.cur[index].name)
box.AddChild(lbl) box.AddChild(lbl)
return box return box
} }
func (p *prtapAdap) ItemAt(index int) gxui.AdapterItem { func (p *prtapAdap) ItemAt(index int) gxui.AdapterItem {
return p.apps[index] return p.cur[index]
} }
func (p *prtapAdap) ItemIndex(item gxui.AdapterItem) int { func (p *prtapAdap) ItemIndex(item gxui.AdapterItem) int {
@@ -90,7 +117,7 @@ func (p *prtapAdap) ItemIndex(item gxui.AdapterItem) int {
if !ok { if !ok {
return -1 return -1
} }
for i, v := range p.apps { for i, v := range p.cur {
if v == it { if v == it {
return i return i
} }
+30 -4
View File
@@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@@ -16,8 +17,9 @@ var (
func uiMain(dri gxui.Driver) { func uiMain(dri gxui.Driver) {
dr = dri dr = dri
catAdap := &StrList{} catAdap := &StrList{}
catAdap.SetStrings(cats) catAdap.SetStrings(linOnly)
appAdap := &prtapAdap{} appAdap := &prtapAdap{}
appAdap.Wine(false)
th := dark.CreateTheme(dr) th := dark.CreateTheme(dr)
win := th.CreateWindow(500, 500, "LinuxPA") win := th.CreateWindow(500, 500, "LinuxPA")
top := th.CreateLinearLayout() top := th.CreateLinearLayout()
@@ -44,16 +46,40 @@ func uiMain(dri gxui.Driver) {
app := applist.Selected().(prtap) app := applist.Selected().(prtap)
dir, fi := path.Split(app.ex) dir, fi := path.Split(app.ex)
var cmd *exec.Cmd var cmd *exec.Cmd
if commEnbl { if app.wine {
cmd = exec.Command("/bin/sh", "-c", ". "+common+" || exit 1;cd \""+dir+"\"; \"./"+fi+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+dir+"\"; wine \""+fi+"\"")
} else { } else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+dir+"\"; \"./"+fi+"\"") if commEnbl {
cmd = exec.Command("/bin/sh", "-c", ". "+common+" || exit 1;cd \""+dir+"\"; \"./"+fi+"\"")
} else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+dir+"\"; \"./"+fi+"\"")
}
} }
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start() cmd.Start()
} }
}) })
if _, err := exec.LookPath("wine"); err == nil {
fmt.Println("Wine found!")
wine := th.CreateButton()
wine.SetType(gxui.ToggleButton)
wine.OnClick(func(gxui.MouseEvent) {
if wine.IsChecked() {
catAdap.SetStrings(cats)
appAdap.Wine(true)
} else {
catAdap.SetStrings(linOnly)
appAdap.Wine(false)
}
})
wine.SetText("Show Windows Apps")
wine.SetChecked(appAdap.wine)
but.AddChild(wine)
} else {
fmt.Println("Wine not found!")
}
but.AddChild(launch) but.AddChild(launch)
top.AddChild(but) top.AddChild(but)
top.AddChild(spl) top.AddChild(spl)