kevinbatdorf/nativephp-launcher
A Laravel/PHP package for adding launcher functionality to NativePHP desktop apps. It offers a lightweight integration for starting or opening NativePHP applications from a Laravel project, simplifying launcher setup and app-launch workflows.
This is a NativePHP-style Android package (Android only, v0.1.0) that turns your Laravel app into a home screen / launcher. It is aimed at kiosk, POS, car-dashboard, TV and dual-screen "companion display" apps rather than general-purpose apps.
Minimal setup:
Launcher::isDefaultHome() on boot. If it returns false, call Launcher::openHomeSettings() and let the user pick your app as the home app. You cannot become home silently — that is an Android user decision.HomeRequested($displayId) early (in EventServiceProvider or a service provider boot()). This is the entry point for "a display wants its home screen".HomeRequested, then use Screens::show($displayId) (from the screens plugin) to route the display to the right screen.Launcher::apps() to populate an app drawer/grid, and Launcher::open($package, $display, $activity) to launch an app onto a specific display.Where to look first: the README's manifest/permissions notes, the Launcher facade, the HomeRequested event class, and the IsHomeScreen trait. Those four are the whole package.
Event-driven display routing. Treat HomeRequested as the single source of truth for "display N is idle and wants home". A typical listener:
Event::listen(HomeRequested::class, function (HomeRequested $event) {
Screens::show($event->displayId);
// or: Launcher::open('com.example.dashboard', $event->displayId);
});
Keep the listener idempotent — HOME can be pressed repeatedly, and each press may re-fire the event.
App drawer / grid. Launcher::apps() gives you installed launchable packages. Cache the result in a property or short-lived cache rather than calling it on every render; the underlying query is not free on low-end devices. Refresh on onResume of the home screen (apps get installed while your launcher is running).
Launching to a specific display. Launcher::open($package, $display, $activity) takes an optional activity. Pass null for the activity when you just want the default launcher activity; pass an explicit activity name for apps that expose multiple entry points (e.g. a "cast" activity vs. a "main" activity). Resolve the display ID from the HomeRequested payload or from the screens plugin, never hard-code 0.
Back handling. Apply the IsHomeScreen trait to the screen/component that represents the root of the home experience. It makes BACK at the root a no-op instead of exiting to... nothing (there is nothing behind home). Use it per-screen, not globally, so sub-screens still pop normally.
Home-screen gating. Build a small "set me as home" prompt using Launcher::isDefaultHome() and Launcher::currentHome(). currentHome() is useful for diagnostics and for telling the user which launcher currently owns the role. Pair the prompt with Launcher::openHomeSettings() and re-check on resume, since the user leaves your app to change the setting.
Kiosk / dedicated device pattern. Because the app runs inside the home task, recents never lists it and it cannot be swiped away as a normal task. That is the intended behaviour for kiosk builds — do not build "relaunch from recents" flows on top of it.
isDefaultHome() / openHomeSettings() are the only levers; there is no API here to force the role. Design your onboarding around the settings round-trip and re-check on resume.HomeRequested or the screens plugin.HomeRequested can fire before your UI is ready. If your listener renders a Livewire component or navigates, ensure the screens plugin is booted. Queueing or deferring the first event after app start is a common fix.IsHomeScreen only covers BACK at the root. It will not stop gestures, recents or home-button behaviour on sub-screens; handle those explicitly.Launcher::open() fails quietly-ish for bad input. Unknown package, missing activity or an invalid display will not launch. Always null-check the result and fall back to Screens::show() or an error UI."~0.1.0" or an exact constraint) and read the changelog before bumping.How can I help you explore Laravel packages today?