diff --git "a/.github/workflows/build\342\200\221debug.yml" "b/.github/workflows/build\342\200\221debug.yml" new file mode 100644 index 000000000..8dd87b6d3 --- /dev/null +++ "b/.github/workflows/build\342\200\221debug.yml" @@ -0,0 +1,63 @@ +name: Android – Debug build + +# ────────────────────────────────────────────────────────────── +# Run on every push to main, on pull‑requests, and on demand +on: + push: + branches: [ main ] # change if your default branch differs + pull_request: + workflow_dispatch: + +# ────────────────────────────────────────────────────────────── +jobs: + debug-apk: + runs-on: ubuntu-latest + + steps: + # 1️⃣ Clone the repo **with sub‑modules** + - name: Checkout sources + uses: actions/checkout@v4 + with: + submodules: recursive # ← critical for Termux:X11 + fetch-depth: 0 # (keeps full history; omit if you like) + + # 2️⃣ Set up JDK 17 and cache the Gradle user‑home dir + - name: Set up Java & Gradle cache + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + cache: 'gradle' + + # 3️⃣ Make the Gradle wrapper executable (Linux runners need this) + - name: Gradle wrapper permissions + run: chmod +x ./gradlew + + # 4️⃣ Build the DEBUG variant (change :app if your module has a different name) + - name: Build debug APK + run: ./gradlew :app:assembleDebug + + # 5️⃣ Upload the APK(s) produced under app/build/outputs/apk/debug/ + - name: Upload APK artefact + uses: actions/upload-artifact@v4 + with: + name: debug-apk + path: app/build/outputs/apk/debug/*.apk + + # ──────────────────────────────────────────────────────────── + # Optional nightly clean‑up so artefacts don’t pile up + cleanup-old-artifacts: + if: ${{ github.event_name == 'schedule' }} + runs-on: ubuntu-latest + steps: + - uses: c-hive/gha-remove-artifacts@v4 + with: + age: '14 days' + +# Enable the clean‑up once a day at 03:00 UTC: +# +# on: +# schedule: +# - cron: '0 3 * * *' +# +# (Uncomment the block above or schedule inside the Actions UI.) diff --git a/app/src/main/java/com/termux/x11/MainActivity.java b/app/src/main/java/com/termux/x11/MainActivity.java index 40cb0ccf4..c33509523 100644 --- a/app/src/main/java/com/termux/x11/MainActivity.java +++ b/app/src/main/java/com/termux/x11/MainActivity.java @@ -10,6 +10,9 @@ import android.Manifest; import android.annotation.SuppressLint; +import android.view.WindowInsets; +import android.view.WindowInsetsController; +import androidx.core.view.WindowCompat; import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationChannel; @@ -71,9 +74,52 @@ import java.util.Map; + + @SuppressLint("ApplySharedPref") @SuppressWarnings({"deprecation", "unused"}) public class MainActivity extends AppCompatActivity { + + private void hideBars() { + WindowInsetsController ctl = + WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView()); + if (ctl != null) { + ctl.hide(WindowInsets.Type.systemBars()); + ctl.setSystemBarsBehavior( + WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); + } + } + + private void setupAutoRehide() { + final View root = getWindow().getDecorView(); + root.setOnApplyWindowInsetsListener((v, insets) -> { + boolean statusVisible = insets.isVisible(WindowInsets.Type.statusBars()); + boolean navVisible = insets.isVisible(WindowInsets.Type.navigationBars()); + if (statusVisible || navVisible) { + v.postDelayed(this::hideBars, /* delay ms */ 50); // pick any delay you like + } + return insets; + }); + } + + + + + + + + + + + + + + + + + + + public static final String ACTION_STOP = "com.termux.x11.ACTION_STOP"; public static final String ACTION_CUSTOM = "com.termux.x11.ACTION_CUSTOM"; @@ -166,6 +212,12 @@ protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main_activity); + WindowCompat.setDecorFitsSystemWindows(getWindow(), false); + hideBars(); + setupAutoRehide(); + + + frm = findViewById(R.id.frame); findViewById(R.id.preferences_button).setOnClickListener((l) -> startActivity(new Intent(this, LoriePreferences.class) {{ setAction(Intent.ACTION_MAIN); }})); findViewById(R.id.help_button).setOnClickListener((l) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/termux/termux-x11/blob/master/README.md#running-graphical-applications")))); diff --git a/app/src/main/java/com/termux/x11/input/TouchInputHandler.java b/app/src/main/java/com/termux/x11/input/TouchInputHandler.java index d49ebc6b9..57f6152ea 100644 --- a/app/src/main/java/com/termux/x11/input/TouchInputHandler.java +++ b/app/src/main/java/com/termux/x11/input/TouchInputHandler.java @@ -262,8 +262,8 @@ static public void refreshInputDevices() { } boolean isDexEvent(MotionEvent event) { - int SOURCE_DEX = InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHSCREEN; - return ((event.getSource() & SOURCE_DEX) == SOURCE_DEX) + return ((event.getSource() & InputDevice.SOURCE_MOUSE) == + InputDevice.SOURCE_MOUSE) && ((event.getSource() & InputDevice.SOURCE_TOUCHPAD) != InputDevice.SOURCE_TOUCHPAD) && (event.getToolType(event.getActionIndex()) == MotionEvent.TOOL_TYPE_FINGER); } @@ -338,8 +338,17 @@ public boolean handleTouchEvent(View view0, View view, MotionEvent event) { break; case MotionEvent.ACTION_SCROLL: - float scrollY = -100 * event.getAxisValue(MotionEvent.AXIS_VSCROLL); - float scrollX = -100 * event.getAxisValue(MotionEvent.AXIS_HSCROLL); + float scrollY = event.getAxisValue(MotionEvent.AXIS_VSCROLL); + float scrollX = event.getAxisValue(MotionEvent.AXIS_HSCROLL); + + if (scrollY == 0 && scrollX == 0) { + scrollY = -event.getAxisValue(MotionEvent.AXIS_RELATIVE_VSCROLL); + scrollX = -event.getAxisValue(MotionEvent.AXIS_RELATIVE_HSCROLL); + } + + scrollY *= -100; + scrollX *= -100; + mInjector.sendMouseWheelEvent(scrollX, scrollY); return true; @@ -853,8 +862,17 @@ boolean mouseButtonDown(int mask) { @SuppressLint("ClickableViewAccessibility") boolean onTouch(View v, MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_SCROLL) { - float scrollY = -100 * e.getAxisValue(MotionEvent.AXIS_VSCROLL); - float scrollX = -100 * e.getAxisValue(MotionEvent.AXIS_HSCROLL); + float scrollY = e.getAxisValue(MotionEvent.AXIS_VSCROLL); + float scrollX = e.getAxisValue(MotionEvent.AXIS_HSCROLL); + + if (scrollY == 0 && scrollX == 0) { + scrollY = -e.getAxisValue(MotionEvent.AXIS_RELATIVE_VSCROLL); + scrollX = -e.getAxisValue(MotionEvent.AXIS_RELATIVE_HSCROLL); + } + + scrollY *= -100; + scrollX *= -100; + mInjector.sendMouseWheelEvent(scrollX, scrollY); return true;