Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.view.WindowInsets;
import android.view.WindowManager;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -90,6 +91,8 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
Map<String, Integer> startPosition = call.argument("startPosition");
int startX = startPosition != null ? startPosition.getOrDefault("x", OverlayConstants.DEFAULT_XY) : OverlayConstants.DEFAULT_XY;
int startY = startPosition != null ? startPosition.getOrDefault("y", OverlayConstants.DEFAULT_XY) : OverlayConstants.DEFAULT_XY;
Integer windowInsetsInteger = call.argument("windowInsets");
int windowInsets = windowInsetsInteger != null ? windowInsetsInteger : ~WindowInsets.Type.ime();


WindowSetup.width = width != null ? width : -1;
Expand All @@ -100,6 +103,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
WindowSetup.overlayTitle = overlayTitle;
WindowSetup.overlayContent = overlayContent == null ? "" : overlayContent;
WindowSetup.positionGravity = positionGravity;
WindowSetup.windowInsets = windowInsets;
WindowSetup.setNotificationVisibility(notificationVisibility);

final Intent intent = new Intent(context, OverlayService.class);
Expand All @@ -112,9 +116,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
} else if (call.method.equals("isOverlayActive")) {
result.success(OverlayService.isRunning);
return;
} else if (call.method.equals("isOverlayActive")) {
result.success(OverlayService.isRunning);
return;
} else if (call.method.equals("moveOverlay")) {
int x = call.argument("x");
int y = call.argument("y");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ final public class OverlayConstants {
static final String CHANNEL_ID = "Overlay Channel";
static final int NOTIFICATION_ID = 4579;
static final int DEFAULT_XY = -6;
static final int MATCH_PARENT = -1;
static final int FULL_COVER = -1999;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;

import androidx.annotation.Nullable;
Expand Down Expand Up @@ -139,7 +140,8 @@ public int onStartCommand(Intent intent, int flags, int startId) {
int width = call.argument("width");
int height = call.argument("height");
boolean enableDrag = call.argument("enableDrag");
resizeOverlay(width, height, enableDrag, result);
int windowInsets = call.argument("windowInsets");
resizeOverlay(width, height, enableDrag, windowInsets == -1 ? null : windowInsets, result);
}
});
overlayMessageChannel.setMessageHandler((message, reply) -> {
Expand All @@ -156,13 +158,14 @@ public int onStartCommand(Intent intent, int flags, int startId) {
int h = displaymetrics.heightPixels;
szWindow.set(w, h);
}

int dx = startX == OverlayConstants.DEFAULT_XY ? 0 : startX;
int dy = startY == OverlayConstants.DEFAULT_XY ? -statusBarHeightPx() : startY;
int dy = startY == OverlayConstants.DEFAULT_XY ? 0 : startY;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowSetup.width == -1999 ? -1 : WindowSetup.width,
WindowSetup.height != -1999 ? WindowSetup.height : screenHeight(),
0,
-statusBarHeightPx(),
WindowSetup.width == -1999 ? WindowManager.LayoutParams.MATCH_PARENT : WindowSetup.width,
WindowSetup.height == -1999 ? WindowManager.LayoutParams.MATCH_PARENT : WindowSetup.height,// screenHeight(),
dx,
dy,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE,
WindowSetup.flag | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
Expand All @@ -173,10 +176,16 @@ public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && WindowSetup.flag == clickableFlag) {
params.alpha = MAXIMUM_OPACITY_ALLOWED_FOR_S_AND_HIGHER;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Log.d("OverlayService", "Setting window insets to " + WindowSetup.windowInsets);
params.setFitInsetsTypes(WindowSetup.windowInsets);
params.setFitInsetsIgnoringVisibility(false);
}

params.gravity = WindowSetup.gravity;
flutterView.setOnTouchListener(this);
windowManager.addView(flutterView, params);
moveOverlay(dx, dy, null);
return START_STICKY;
}

Expand Down Expand Up @@ -240,12 +249,17 @@ private void updateOverlayFlag(MethodChannel.Result result, String flag) {
}
}

private void resizeOverlay(int width, int height, boolean enableDrag, MethodChannel.Result result) {
private void resizeOverlay(int width, int height, boolean enableDrag, Integer windowInsets, MethodChannel.Result result) {
if (windowManager != null) {
WindowManager.LayoutParams params = (WindowManager.LayoutParams) flutterView.getLayoutParams();
params.width = (width == -1999 || width == -1) ? -1 : dpToPx(width);
params.height = (height != 1999 || height != -1) ? dpToPx(height) : height;
params.width = (width == OverlayConstants.FULL_COVER || width == OverlayConstants.MATCH_PARENT) ? OverlayConstants.MATCH_PARENT : dpToPx(width);
params.height = (height == OverlayConstants.FULL_COVER || height == OverlayConstants.MATCH_PARENT) ? OverlayConstants.MATCH_PARENT : dpToPx(height);
WindowSetup.enableDrag = enableDrag;

if (windowInsets != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
params.setFitInsetsTypes(windowInsets);
}

windowManager.updateViewLayout(flutterView, params);
result.success(true);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import android.view.Gravity;
import android.view.WindowInsets;
import android.view.WindowManager;

import androidx.core.app.NotificationCompat;
Expand All @@ -20,6 +21,7 @@ public abstract class WindowSetup {
static String positionGravity = "none";
static int notificationVisibility = NotificationCompat.VISIBILITY_PRIVATE;
static boolean enableDrag = false;
static int windowInsets = WindowInsets.Type.systemBars();


static void setNotificationVisibility(String name) {
Expand Down
100 changes: 99 additions & 1 deletion example/lib/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,34 @@ class _HomePageState extends State<HomePage> {
final _receivePort = ReceivePort();
SendPort? homePort;
String? latestMessageFromOverlay;

// Selected window insets types
Set<int> selectedInsetsTypes = {WindowInsetsType.statusBars, WindowInsetsType.navigationBars};

// Collapsible section state
bool _isInsetsExpanded = false;

// Available window insets types
final List<MapEntry<String, int>> insetsTypes = [
MapEntry('Status Bars', WindowInsetsType.statusBars),
MapEntry('Navigation Bars', WindowInsetsType.navigationBars),
MapEntry('Caption Bar', WindowInsetsType.captionBar),
MapEntry('IME', WindowInsetsType.ime),
MapEntry('System Gestures', WindowInsetsType.systemGestures),
MapEntry('Mandatory System Gestures', WindowInsetsType.mandatorySystemGestures),
MapEntry('Tappable Element', WindowInsetsType.tappableElement),
MapEntry('Display Cutout', WindowInsetsType.displayCutout),
MapEntry('Window Decor', WindowInsetsType.windowDecor),
MapEntry('System Overlays', WindowInsetsType.systemOverlays),
];

int combineSelectedInsets() {
int combined = 0;
for (var type in selectedInsetsTypes) {
combined |= type;
}
return combined;
}

@override
void initState() {
Expand All @@ -42,9 +70,59 @@ class _HomePageState extends State<HomePage> {
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
body: SingleChildScrollView(
child: Column(
children: [
InkWell(
onTap: () {
setState(() {
_isInsetsExpanded = !_isInsetsExpanded;
});
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
child: Row(
children: [
Icon(
_isInsetsExpanded ? Icons.expand_less : Icons.expand_more,
size: 20,
),
const SizedBox(width: 4),
const Text(
'Window Insets',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
),
),
),
if (_isInsetsExpanded)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 4.0),
child: Wrap(
spacing: 4,
runSpacing: 4,
children: insetsTypes.map((entry) {
final isSelected = selectedInsetsTypes.contains(entry.value);
return FilterChip(
label: Text(entry.key, style: const TextStyle(fontSize: 11)),
selected: isSelected,
visualDensity: VisualDensity.compact,
padding: EdgeInsets.zero,
onSelected: (selected) {
setState(() {
if (selected) {
selectedInsetsTypes.add(entry.value);
} else {
selectedInsetsTypes.remove(entry.value);
}
});
},
);
}).toList(),
),
),
const Divider(height: 1),
TextButton(
onPressed: () async {
final status = await FlutterOverlayWindow.isPermissionGranted();
Expand Down Expand Up @@ -75,11 +153,31 @@ class _HomePageState extends State<HomePage> {
height: (MediaQuery.of(context).size.height * 0.6).toInt(),
width: WindowSize.matchParent,
startPosition: const OverlayPosition(0, -259),
windowInsets: combineSelectedInsets(),
);
},
child: const Text("Show Overlay"),
),
const SizedBox(height: 10.0),
TextButton(
onPressed: () async {
if (await FlutterOverlayWindow.isActive()) return;
await FlutterOverlayWindow.showOverlay(
enableDrag: false,
overlayTitle: "X-SLAYER",
overlayContent: 'Fullscreen Overlay Enabled',
flag: OverlayFlag.defaultFlag,
visibility: NotificationVisibility.visibilityPublic,
//positionGravity: PositionGravity.none,
height: WindowSize.fullCover,
width: WindowSize.fullCover,
startPosition: const OverlayPosition(0, 0),
windowInsets: combineSelectedInsets(),
);
},
child: const Text("Show Fullscreen Overlay"),
),
const SizedBox(height: 10.0),
TextButton(
onPressed: () async {
final status = await FlutterOverlayWindow.isActive();
Expand Down
2 changes: 2 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window_example/home_page.dart';
import 'package:flutter_overlay_window_example/overlays/fullscreen_overlay.dart';
import 'package:flutter_overlay_window_example/overlays/true_caller_overlay.dart';

void main() {
Expand All @@ -14,6 +15,7 @@ void overlayMain() {
const MaterialApp(
debugShowCheckedModeBanner: false,
home: TrueCallerOverlay(),
// home: FullscreenOverlay(), /// Uncomment to test FullscreenOverlay
),
);
}
Expand Down
40 changes: 40 additions & 0 deletions example/lib/overlays/fullscreen_overlay.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';

class FullscreenOverlay extends StatelessWidget {
const FullscreenOverlay({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Material(
color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 3),
),
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Overlay With White Border',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
ElevatedButton(
onPressed: FlutterOverlayWindow.closeOverlay,
child: Text(
'Close',
))
],
),
),
),
),
);
}
}
Loading