Skip to content

Commit

Permalink
Big update. Replacing Xvfb and Xwayland with builtin X server.
Browse files Browse the repository at this point in the history
  • Loading branch information
twaik committed May 25, 2023
1 parent 62bf17d commit ee2224e
Show file tree
Hide file tree
Showing 143 changed files with 15,281 additions and 5,798 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/debug_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ jobs:
- name: Build companion package
run: |
./build_termux_package
- name: Store generated APK file
- name: Copy loader to target directory
run: |
cp ./shell-loader/build/outputs/apk/debug/shell-loader-debug.apk ./app/build/outputs/apk/debug/shell-loader-nightly.apk
- name: Store generated files
uses: actions/upload-artifact@v3
with:
name: termux-x11
Expand Down
128 changes: 107 additions & 21 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,38 +1,124 @@
[submodule "app/src/main/cpp/wayland"]
path = app/src/main/cpp/wayland
url = https://gitlab.freedesktop.org/wayland/wayland
[submodule "app/src/main/cpp/libandroid-shmem"]
path = app/src/main/cpp/libandroid-shmem
url = https://github.com/termux/libandroid-shmem
ignore = dirty
[submodule "app/src/main/cpp/libmd"]
path = app/src/main/cpp/libmd
url = https://git.hadrons.org/git/libmd
ignore = dirty
[submodule "app/src/main/cpp/libtirpc"]
path = app/src/main/cpp/libtirpc
url = https://github.com/alisw/libtirpc
ignore = dirty
[submodule "app/src/main/cpp/drm"]
path = app/src/main/cpp/drm
url = https://gitlab.freedesktop.org/mesa/drm
ignore = dirty
[submodule "app/src/main/cpp/freetype"]
path = app/src/main/cpp/freetype
url = https://gitlab.freedesktop.org/freetype/freetype
ignore = dirty
[submodule "app/src/main/cpp/pixman"]
path = app/src/main/cpp/pixman
url = https://gitlab.freedesktop.org/pixman/pixman
ignore = dirty
[submodule "app/src/main/cpp/libfontenc"]
path = app/src/main/cpp/libfontenc
url = https://gitlab.freedesktop.org/xorg/lib/libfontenc
ignore = dirty
[submodule "app/src/main/cpp/libxext"]
path = app/src/main/cpp/libxext
url = https://gitlab.freedesktop.org/xorg/lib/libxext
ignore = dirty
[submodule "app/src/main/cpp/libxau"]
path = app/src/main/cpp/libxau
url = https://gitlab.freedesktop.org/xorg/lib/libxau
ignore = dirty
[submodule "app/src/main/cpp/libxcb"]
path = app/src/main/cpp/libxcb
url = https://gitlab.freedesktop.org/xorg/lib/libxcb
ignore = dirty
[submodule "app/src/main/cpp/xorgproto"]
path = app/src/main/cpp/xorgproto
url = https://gitlab.freedesktop.org/xorg/proto/xorgproto
[submodule "app/src/main/cpp/libxdmcp"]
path = app/src/main/cpp/libxdmcp
url = https://gitlab.freedesktop.org/xorg/lib/libxdmcp
ignore = dirty
[submodule "app/src/main/cpp/xcbproto"]
path = app/src/main/cpp/xcbproto
url = https://gitlab.freedesktop.org/xorg/proto/xcbproto
[submodule "app/src/main/cpp/libxfont"]
path = app/src/main/cpp/libxfont
url = https://gitlab.freedesktop.org/xorg/lib/libxfont
ignore = dirty
[submodule "app/src/main/cpp/libXau"]
path = app/src/main/cpp/libXau
url = https://gitlab.freedesktop.org/xorg/lib/libxau
[submodule "app/src/main/cpp/libxrender"]
path = app/src/main/cpp/libxrender
url = https://gitlab.freedesktop.org/xorg/lib/libxrender
ignore = dirty
[submodule "app/src/main/cpp/libxcb-errors"]
path = app/src/main/cpp/libxcb-errors
url = https://gitlab.freedesktop.org/xorg/lib/libxcb-errors
[submodule "app/src/main/cpp/libxrandr"]
path = app/src/main/cpp/libxrandr
url = https://gitlab.freedesktop.org/xorg/lib/libxrandr
ignore = dirty
[submodule "app/src/main/cpp/libxkbfile"]
path = app/src/main/cpp/libxkbfile
url = https://gitlab.freedesktop.org/xorg/lib/libxkbfile
ignore = dirty
[submodule "app/src/main/cpp/libxshmfence"]
path = app/src/main/cpp/libxshmfence
url = https://gitlab.freedesktop.org/xorg/lib/libxshmfence
ignore = dirty
[submodule "app/src/main/cpp/libxtrans"]
path = app/src/main/cpp/libxtrans
url = https://gitlab.freedesktop.org/xorg/lib/libxtrans
ignore = dirty
[submodule "app/src/main/cpp/libepoxy"]
path = app/src/main/cpp/libepoxy
url = https://github.com/anholt/libepoxy
ignore = dirty
[submodule "app/src/main/cpp/libxcvt"]
path = app/src/main/cpp/libxcvt
url = https://gitlab.freedesktop.org/xorg/lib/libxcvt
ignore = dirty
[submodule "app/src/main/cpp/libxfixes"]
path = app/src/main/cpp/libxfixes
url = https://gitlab.freedesktop.org/xorg/lib/libxfixes
ignore = dirty
[submodule "app/src/main/cpp/libxxf86vm"]
path = app/src/main/cpp/libxxf86vm
url = https://gitlab.freedesktop.org/xorg/lib/libxxf86vm
ignore = dirty
[submodule "app/src/main/cpp/libx11"]
path = app/src/main/cpp/libx11
url = https://gitlab.freedesktop.org/xorg/lib/libx11
ignore = dirty
[submodule "app/src/main/cpp/xcbproto"]
path = app/src/main/cpp/xcbproto
url = https://gitlab.freedesktop.org/xorg/proto/xcbproto
ignore = dirty
[submodule "app/src/main/cpp/xorgproto"]
path = app/src/main/cpp/xorgproto
url = https://gitlab.freedesktop.org/xorg/proto/xorgproto
ignore = dirty
[submodule "app/src/main/cpp/xkbcomp"]
path = app/src/main/cpp/xkbcomp
url = https://gitlab.freedesktop.org/xorg/app/xkbcomp
ignore = dirty
[submodule "app/src/main/cpp/xserver"]
path = app/src/main/cpp/xserver
url = https://gitlab.freedesktop.org/xorg/xserver
ignore = dirty
[submodule "app/src/main/cpp/mesa"]
path = app/src/main/cpp/mesa
url = https://gitlab.freedesktop.org/mesa/mesa
ignore = dirty
[submodule "app/src/main/cpp/virglrenderer"]
path = app/src/main/cpp/virglrenderer
url = https://gitlab.freedesktop.org/virgl/virglrenderer
ignore = dirty
[submodule "app/src/main/cpp/libxkbcommon"]
path = app/src/main/cpp/libxkbcommon
url = https://github.com/xkbcommon/libxkbcommon
ignore = dirty
[submodule "app/src/main/cpp/libffi"]
path = app/src/main/cpp/libffi
url = https://android.googlesource.com/platform/external/libffi/
[submodule "app/src/main/cpp/wayland-protocols"]
path = app/src/main/cpp/wayland-protocols
url = https://gitlab.freedesktop.org/wayland/wayland-protocols
[submodule "app/src/main/cpp/libxcb-errors"]
path = app/src/main/cpp/libxcb-errors
url = https://gitlab.freedesktop.org/xorg/lib/libxcb-errors
ignore = dirty
[submodule "app/src/main/cpp/flac"]
path = app/src/main/cpp/flac
url = https://github.com/xiph/flac
ignore = dirty
40 changes: 28 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@

[![Nightly build](https://github.com/termux/termux-x11/actions/workflows/debug_build.yml/badge.svg?branch=master)](https://github.com/termux/termux-x11/actions/workflows/debug_build.yml) [![Join the chat at https://gitter.im/termux/termux](https://badges.gitter.im/termux/termux.svg)](https://gitter.im/termux/termux) [![Join the Termux discord server](https://img.shields.io/discord/641256914684084234?label=&logo=discord&logoColor=ffffff&color=5865F2)](https://discord.gg/HXpF69X)

A [Termux](https://termux.com) add-on app providing Android frontend for Xwayland.
A [Termux](https://termux.com) X11 server add-on app.

## About
Termux:X11 uses [Wayland](https://wayland.freedesktop.org/) display protocol. a modern replacement and the predecessor of the [X.org](https://www.x.org/wiki) server.
Pay attention that it is not a full-fledged Wayland server and it can not handle Wayland apps except Xwayland.
Termux:X11 is a fully fledged X server. It is built with Android NDK and optimized to be used with Termux.

## Caveat
## Submodules caveat
This repo uses submodules. Use

```
Expand All @@ -23,26 +22,41 @@ or
```

## How does it work?
The Termux:X11 app's companion package executable creates socket through `$XDG_RUNTIME_DIR` in Termux directory by default.

The wayland sockets is the way for the graphical applications to communicate with. Termux X11 applications do not have wayland support yet, this kind of setup may not be straightforward and therefore additional packages should be installed in order for X11 applications to be run in Termux:X11
Just like any other X server.

## Setup Instructions
For this one you must enable the `x11-repo` repository can be done by executing `pkg install x11-repo` command

For X applications to work, you must install Termux-x11 companion package. You can do that by downloading an artifact from [last successful build](https://github.com/termux/termux-x11/actions/workflows/debug_build.yml) and installing `*.apk` and `*.deb` (if you use termux with `pkg`) or `*.tar.xz` (if you use termux with `pacman`) files.
Or you can install nightly companion package from repositories with `pkg in x11-repo && pkg in termux-x11-nightly`

## Running Graphical Applications
to work with GUI applications, start Termux:X11 first. a toast message saying `Service was Created` indicates that it should be ready to use

then you can start your desired graphical application by doing:
You can start your desired graphical application by doing:
```
~ $ XDG_RUNTIME_DIR=${TMPDIR} termux-x11 :1 &
~ $ termux-x11 :1 &
~ $ env DISPLAY=:1 dbus-launch --exit-with-session xfce4-session
```
You may replace `xfce4-session` if you use other than Xfce

If you're done using Termux:X11 just simply exit it through it's notification drawer by expanding the Termux:X11 notification then "Exit"
But you should pay attention that `termux-x11` command is still running and can not be killed this way.

## Using with proot environment
If you plan to use the program with proot, keep in mind that you need to launch proot/proot-distro with the --shared-tmp option.
If passing this option is not possible, set the TMPDIR environment variable to point to the directory that corresponds to /tmp in the target container.
If you are using proot-distro you should know that it is possible to start `termux-x11` command from inside proot container.

## Using with chroot environment
If you plan to use the program with chroot or unshare, you must to run it as root and set the TMPDIR environment variable to point to the directory that corresponds to /tmp in the target container.
This directory must be accessible from the shell from which you launch termux-x11, i.e. it must be in the same SELinux context, same mount namespace, and so on.
Also you must set `XKB_CONFIG_ROOT` environment variable pointing to container's `/usr/share/X11/xkb` directory, otherwise you will have `xkbcomp`-related errors.
You can get loader for nightly build from an artifact of [last successful build](https://github.com/termux/termux-x11/actions/workflows/debug_build.yml)
```
export XKB_CONFIG_ROOT=/path/to/chroot/container/usr/share/xkb
export TMPDIR=/path/to/chroot/container/tmp
export CLASSPATH=/path/to/loader.apk
/system/bin/app_process / com.termux.x11.Loader :0
```

### Logs
If you need to obtain logs from the `com.termux.x11` application,
Expand Down Expand Up @@ -100,7 +114,7 @@ In touchpad emulation mode you can use the following gestures:
* Three-finger swipe down to show-hide additional keys bar.

## Font or scaling is too big!
Some apps may have issues with wayland regarding DPI. please see https://wiki.archlinux.org/title/HiDPI on how to override application-specific DPI or scaling.
Some apps may have issues with X server regarding DPI. please see https://wiki.archlinux.org/title/HiDPI on how to override application-specific DPI or scaling.

You can fix this in your window manager settings (in the case of xfce4 and lxqt via Applications Menu > Settings > Appearance). Look for the DPI value, if it is disabled enable it and adjust its value until the fonts are the appropriate size.
<details>
Expand All @@ -109,6 +123,8 @@ You can fix this in your window manager settings (in the case of xfce4 and lxqt
![image](./img/dpi-scale.png)
</details>

Also you can choose desired DPI in preferences of Termux:X11 app

## Using with 3rd party apps
It is possible to use Termux:X11 with 3rd party apps.
Check how `shell-loader/src/main/java/com/termux/x11/Loader.java` works.
Expand Down
34 changes: 24 additions & 10 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
apply plugin: 'com.android.application'

android {
namespace 'com.termux.x11'
compileSdkVersion 33
defaultConfig {
applicationId "com.termux.x11"
minSdkVersion 24
minSdkVersion 26

/*
* Do not increase targetSdkVersion
Expand All @@ -13,12 +14,12 @@ android {
*/
//noinspection ExpiredTargetSdkVersion,OldTargetApi
targetSdkVersion 28
versionCode 11
versionName "1.02.07"
versionCode 12
versionName "1.02.10"

externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_static"
arguments "-DANDROID_STL=c++_shared"
}
}
}
Expand All @@ -43,9 +44,23 @@ android {
}
}

splits {
abi {
enable true
reset()

include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
universalApk true //generate an additional APK that contains all the ABIs
}
}

buildFeatures {
aidl true
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_9
targetCompatibility JavaVersion.VERSION_1_9
}

externalNativeBuild {
Expand All @@ -68,15 +83,14 @@ android {

dependencies {
//noinspection DifferentStdlibGradleVersion
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.6.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
implementation 'com.termux.termux-app:termux-shared:2f5a6f7de6'
implementation 'com.google.android.material:material:1.8.0'
implementation 'com.google.android.material:material:1.9.0'
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleDependency
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
Expand Down
25 changes: 19 additions & 6 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.termux.x11"
android:installLocation="internalOnly"
>
android:installLocation="internalOnly">

<uses-permission android:name="com.termux.permission.RUN_COMMAND" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
Expand All @@ -19,6 +16,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".MainActivity"
Expand Down Expand Up @@ -47,6 +45,7 @@
android:resizeableActivity="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
Expand All @@ -55,8 +54,22 @@
android:taskAffinity=".GettingStartedActivity"
android:theme="@style/Theme.BaseActivity.DayNight.NoActionBar"
android:exported="true" />
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="false"/>
<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />

<service android:name=".utils.KeyInterceptor"
android:exported="true"
android:label="Termux:X11 KeyInterceptor"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>

<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>

</application>
<queries>
<package android:name="com.termux" />
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/aidl/com/termux/x11/ICmdEntryInterface.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.termux.x11;

// This interface is used by utility on termux side.
interface ICmdEntryInterface {
void outputResize(int width, int height);
void windowChanged(in Surface surface);
ParcelFileDescriptor getXConnection();
ParcelFileDescriptor getLogcatOutput();
}

0 comments on commit ee2224e

Please sign in to comment.