6 Commits

Author SHA1 Message Date
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 105 additions and 20 deletions
+4 -5
View File
@@ -1,21 +1,21 @@
# 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
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.
# 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).
# 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 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
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,7 +25,6 @@ Photos are found [Here](https://goo.gl/photos/VtBUL6DyZTMidj5n6)
# TODO (Might be in order)
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 updater for .AppImage files
1. Download .AppImage files (maybe)
+37 -4
View File
@@ -14,6 +14,8 @@ import (
var (
appMaster map[string][]prtap
cats []string
wineOnly []string
linOnly []string
conf *os.File
common string
commEnbl bool
@@ -24,6 +26,7 @@ type prtap struct {
cat string
ex string
desc string
wine bool
}
func main() {
@@ -43,7 +46,7 @@ func main() {
appstmp, _ := pa.Readdir(-1)
var folds []string
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())
}
}
@@ -53,11 +56,29 @@ func main() {
pat := processApp(fi)
if (pat != prtap{}) {
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:]...)
break
}
}
}
}
appMaster[pat.cat] = append(appMaster[pat.cat], pat)
}
}
sort.Strings(linOnly)
sort.Strings(wineOnly)
sort.Strings(cats)
gl.StartDriver(uiMain)
}
@@ -72,13 +93,13 @@ func processApp(fi *os.File) (out prtap) {
fil, _ = os.Open(fi.Name() + "/appinfo.ini")
out.cat = getCat(fil)
} else {
out.cat = "other"
out.cat = "Other"
}
if out.name == "" {
out.name = path.Base(fi.Name())
}
if out.cat == "" {
out.cat = "other"
out.cat = "Other"
}
//executable detection
wd, _ := os.Getwd()
@@ -116,6 +137,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{}
}
+34 -7
View File
@@ -15,16 +15,43 @@ import (
type prtapAdap struct {
gxui.AdapterBase
apps []prtap
wine bool
master []prtap
cur []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)
}
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 {
@@ -32,7 +59,7 @@ func (p *prtapAdap) Create(th gxui.Theme, index int) gxui.Control {
box.SetPadding(math.CreateSpacing(2))
box.SetDirection(gxui.LeftToRight)
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 {
var pics []string
fi, _ := fold.Readdirnames(-1)
@@ -76,13 +103,13 @@ func (p *prtapAdap) Create(th gxui.Theme, index int) gxui.Control {
box.AddChild(icon)
}
lbl := th.CreateLabel()
lbl.SetText(p.apps[index].name)
lbl.SetText(p.cur[index].name)
box.AddChild(lbl)
return box
}
func (p *prtapAdap) ItemAt(index int) gxui.AdapterItem {
return p.apps[index]
return p.cur[index]
}
func (p *prtapAdap) ItemIndex(item gxui.AdapterItem) int {
@@ -90,7 +117,7 @@ func (p *prtapAdap) ItemIndex(item gxui.AdapterItem) int {
if !ok {
return -1
}
for i, v := range p.apps {
for i, v := range p.cur {
if v == it {
return i
}
+30 -4
View File
@@ -1,6 +1,7 @@
package main
import (
"fmt"
"os"
"os/exec"
"path"
@@ -16,8 +17,9 @@ var (
func uiMain(dri gxui.Driver) {
dr = dri
catAdap := &StrList{}
catAdap.SetStrings(cats)
catAdap.SetStrings(linOnly)
appAdap := &prtapAdap{}
appAdap.Wine(false)
th := dark.CreateTheme(dr)
win := th.CreateWindow(500, 500, "LinuxPA")
top := th.CreateLinearLayout()
@@ -44,16 +46,40 @@ func uiMain(dri gxui.Driver) {
app := applist.Selected().(prtap)
dir, fi := path.Split(app.ex)
var cmd *exec.Cmd
if commEnbl {
cmd = exec.Command("/bin/sh", "-c", ". "+common+" || exit 1;cd \""+dir+"\"; \"./"+fi+"\"")
if app.wine {
cmd = exec.Command("/bin/sh", "-c", "cd \""+dir+"\"; wine \""+fi+"\"")
} 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.Stdout = os.Stdout
cmd.Stderr = os.Stderr
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)
top.AddChild(but)
top.AddChild(spl)