add floating window setting (#8279)

* Set `disable-floating-window` in client ui, it shows enabled when
  option is enabled and has floating window permission.
* Remove ignore battery setting because not work on every device.
* When the phone orientation changes, make the Y coordinate change
  proportionally, when changing back, the floating window position is still the original one.
* Add custom client option `floating-window-untouchable` to make the
  click event pass through the floating window automically. Set it untouchable automically when transparency is 0.
* On my phone, floating window size 16 no works and 32 works, so keep
  the size range [32, 320]

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages 2024-06-07 11:04:18 +08:00 committed by GitHub
parent 6d1d844b14
commit 64d0fb17f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 155 additions and 14 deletions

View File

@ -38,18 +38,21 @@ class FloatingWindowService : Service(), View.OnTouchListener {
private var dragging = false
private var lastDownX = 0f
private var lastDownY = 0f
private var viewCreated = false;
companion object {
private val logTag = "floatingService"
private var firsCreate = true
private var firstCreate = true
private var viewWidth = 120
private var viewHeight = 120
private const val MIN_VIEW_SIZE = 32 // size 0 does not help prevent the service from being killed
private const val MAX_VIEW_SIZE = 320
private var viewUntouchable = false
private var viewTransparency = 1f // 0 means invisible but can help prevent the service from being killed
private var customSvg = ""
private var lastLayoutX = 0
private var lastLayoutY = 0
private var lastOrientation = Configuration.ORIENTATION_UNDEFINED
}
override fun onBind(intent: Intent): IBinder? {
@ -60,8 +63,8 @@ class FloatingWindowService : Service(), View.OnTouchListener {
super.onCreate()
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
try {
if (firsCreate) {
firsCreate = false
if (firstCreate) {
firstCreate = false
onFirstCreate(windowManager)
}
Log.d(logTag, "floating window size: $viewWidth x $viewHeight, transparency: $viewTransparency, lastLayoutX: $lastLayoutX, lastLayoutY: $lastLayoutY, customSvg: $customSvg")
@ -75,6 +78,7 @@ class FloatingWindowService : Service(), View.OnTouchListener {
@SuppressLint("ClickableViewAccessibility")
private fun createView(windowManager: WindowManager) {
floatingView = ImageView(this)
viewCreated = true
originalDrawable = resources.getDrawable(R.drawable.floating_window, null)
if (customSvg.isNotEmpty()) {
try {
@ -131,7 +135,10 @@ class FloatingWindowService : Service(), View.OnTouchListener {
floatingView.setOnTouchListener(this)
floatingView.alpha = viewTransparency * 1f
val flags = FLAG_LAYOUT_IN_SCREEN or FLAG_NOT_TOUCH_MODAL or FLAG_NOT_FOCUSABLE
var flags = FLAG_LAYOUT_IN_SCREEN or FLAG_NOT_TOUCH_MODAL or FLAG_NOT_FOCUSABLE
if (viewUntouchable || viewTransparency == 0f) {
flags = flags or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
}
layoutParams = WindowManager.LayoutParams(
viewWidth / 2,
viewHeight,
@ -166,6 +173,8 @@ class FloatingWindowService : Service(), View.OnTouchListener {
}
}
}
// untouchable
viewUntouchable = FFI.getLocalOption("floating-window-untouchable") == "Y"
// transparency
FFI.getLocalOption("floating-window-transparency").let {
if (it.isNotEmpty()) {
@ -188,11 +197,14 @@ class FloatingWindowService : Service(), View.OnTouchListener {
// position
lastLayoutX = 0
lastLayoutY = (wh.second - viewHeight) / 2
lastOrientation = resources.configuration.orientation
}
override fun onDestroy() {
super.onDestroy()
windowManager.removeView(floatingView)
if (viewCreated) {
windowManager.removeView(floatingView)
}
}
private fun performClick() {
@ -200,7 +212,6 @@ class FloatingWindowService : Service(), View.OnTouchListener {
}
override fun onTouch(view: View?, event: MotionEvent?): Boolean {
if (viewTransparency == 0f) return false
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
dragging = false
@ -257,7 +268,19 @@ class FloatingWindowService : Service(), View.OnTouchListener {
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
moveToScreenSide(true)
if (newConfig.orientation != lastOrientation) {
lastOrientation = newConfig.orientation
val wh = getScreenSize(windowManager)
Log.d(logTag, "orientation: $lastOrientation, screen size: ${wh.first} x ${wh.second}")
val newW = wh.first
val newH = wh.second
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE || newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
// Proportional change
layoutParams.x = (layoutParams.x.toFloat() / newH.toFloat() * newW.toFloat()).toInt()
layoutParams.y = (layoutParams.y.toFloat() / newW.toFloat() * newH.toFloat()).toInt()
}
moveToScreenSide()
}
}
private fun showPopupMenu() {

View File

@ -365,14 +365,10 @@ class MainActivity : FlutterActivity() {
}
}
private var disableFloatingWindow: Boolean? = null
override fun onStop() {
super.onStop()
if (disableFloatingWindow == null) {
disableFloatingWindow = FFI.getLocalOption("disable-floating-window") == "Y"
Log.d(logTag, "disableFloatingWindow: $disableFloatingWindow")
}
if (disableFloatingWindow != true && MainService.isReady) {
val disableFloatingWindow = FFI.getLocalOption("disable-floating-window") == "Y"
if (!disableFloatingWindow && MainService.isReady) {
startService(Intent(this, FloatingWindowService::class.java))
}
}

View File

@ -247,6 +247,7 @@ class MainService : Service() {
override fun onDestroy() {
checkMediaPermission()
stopService(Intent(this, FloatingWindowService::class.java))
super.onDestroy()
}

View File

@ -36,9 +36,11 @@ class SettingsPage extends StatefulWidget implements PageShape {
const url = 'https://rustdesk.com/';
class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
final _hasIgnoreBattery = androidVersion >= 26;
final _hasIgnoreBattery =
false; //androidVersion >= 26; // remove because not work on every device
var _ignoreBatteryOpt = false;
var _enableStartOnBoot = false;
var _floatingWindowDisabled = false;
var _enableAbr = false;
var _denyLANDiscovery = false;
var _onlyWhiteList = false;
@ -86,6 +88,14 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
_enableStartOnBoot = enableStartOnBoot;
}
var floatingWindowDisabled =
bind.mainGetLocalOption(key: kOptionDisableFloatingWindow) == "Y" ||
!await AndroidPermissionManager.check(kSystemAlertWindow);
if (floatingWindowDisabled != _floatingWindowDisabled) {
update = true;
_floatingWindowDisabled = floatingWindowDisabled;
}
final enableAbrRes = option2bool(
kOptionEnableAbr, await bind.mainGetOption(key: kOptionEnableAbr));
if (enableAbrRes != _enableAbr) {
@ -493,6 +503,32 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
gFFI.invokeMethod(AndroidChannel.kSetStartOnBootOpt, toValue);
}));
onFloatingWindowChanged(bool toValue) async {
if (toValue) {
if (!await AndroidPermissionManager.check(kSystemAlertWindow)) {
if (!await AndroidPermissionManager.request(kSystemAlertWindow)) {
return;
}
}
}
final disable = !toValue;
bind.mainSetLocalOption(
key: kOptionDisableFloatingWindow,
value: disable ? 'Y' : defaultOptionNo);
setState(() => _floatingWindowDisabled = disable);
}
enhancementsTiles.add(SettingsTile.switchTile(
initialValue: !_floatingWindowDisabled,
title: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(translate('Floating window')),
Text('* ${translate('floating_window_tip')}',
style: Theme.of(context).textTheme.bodySmall),
]),
onToggle: bind.mainIsOptionFixed(key: kOptionDisableFloatingWindow)
? null
: onFloatingWindowChanged));
final disabledSettings = bind.isDisableSettings();
final settings = SettingsList(
sections: [

View File

@ -2096,6 +2096,7 @@ pub mod keys {
// android floating window options
pub const OPTION_DISABLE_FLOATING_WINDOW: &str = "disable-floating-window";
pub const OPTION_FLOATING_WINDOW_SIZE: &str = "floating-window-size";
pub const OPTION_FLOATING_WINDOW_UNTOUCHABLE: &str = "floating-window-untouchable";
pub const OPTION_FLOATING_WINDOW_TRANSPARENCY: &str = "floating-window-transparency";
pub const OPTION_FLOATING_WINDOW_SVG: &str = "floating-window-svg";
@ -2156,6 +2157,7 @@ pub mod keys {
OPTION_FLUTTER_CURRENT_AB_NAME,
OPTION_DISABLE_FLOATING_WINDOW,
OPTION_FLOATING_WINDOW_SIZE,
OPTION_FLOATING_WINDOW_UNTOUCHABLE,
OPTION_FLOATING_WINDOW_TRANSPARENCY,
OPTION_FLOATING_WINDOW_SVG,
];

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "收到新的语音呼叫请求。如果您接受,音频将切换为语音通信。"),
("texture_render_tip", "使用纹理渲染,使图片更加流畅。 如果您遭遇渲染问题,可尝试关闭此选项。"),
("Use texture rendering", "使用纹理渲染"),
("Floating window", "悬浮窗"),
("floating_window_tip", "有助于保持RustDesk后台服务"),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Byl přijat nový požadavek na hlasové volání. Pokud hovor přijmete, přepne se zvuk na hlasovou komunikaci."),
("texture_render_tip", "Použít vykreslování textur, aby byly obrázky hladší."),
("Use texture rendering", "Použít vykreslování textur"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Eine neue Sprachanrufanfrage wurde empfangen. Wenn Sie die Anfrage annehmen, wird der Ton auf Sprachkommunikation umgeschaltet."),
("texture_render_tip", "Verwenden Sie Textur-Rendering, um die Bilder glatter zu machen."),
("Use texture rendering", "Textur-Rendering verwenden"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -229,5 +229,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("confirm_clear_Wayland_screen_selection_tip", "Are you sure to clear the Wayland screen selection?"),
("android_new_voice_call_tip", "A new voice call request was received. If you accept, the audio will switch to voice communication."),
("texture_render_tip", "Use texture rendering to make the pictures smoother. You could try disabling this option if you encounter rendering issues."),
("floating_window_tip", "It helps to keep RustDesk background service"),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Se ha recibido una nueva solicitud de llamada de voz. Si aceptas el audio cambiará a comunicación de voz."),
("texture_render_tip", "Usar renderizado de texturas para hacer las imágenes más suaves."),
("Use texture rendering", "Usar renderizado de texturas"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "یک درخواست تماس صوتی جدید دریافت شد. اگر بپذیرید، صدا به ارتباط صوتی تغییر خواهد کرد."),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Une nouvelle demande dappel vocal a été reçue. Si vous acceptez, laudio passera à la communication vocale."),
("texture_render_tip", "Utilisez le rendu des textures pour rendre les images plus fluides."),
("Use texture rendering", "Utiliser le rendu de texture"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "È stata ricevuta una nuova richiesta di chiamata vocale. Se accetti, l'audio passerà alla comunicazione vocale."),
("texture_render_tip", "Usa il rendering texture per rendere le immagini più fluide. Se riscontri problemi di rendering prova a disabilitare questa opzione."),
("Use texture rendering", "Usa rendering texture"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Tika saņemts jauns balss zvana pieprasījums. Ja piekrītat, audio pārslēgsies uz balss saziņu."),
("texture_render_tip", "Izmantojiet tekstūras renderēšanu, lai attēli būtu vienmērīgāki. Varat mēģināt atspējot šo opciju, ja rodas renderēšanas problēmas."),
("Use texture rendering", "Izmantot tekstūras renderēšanu"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Er is een nieuwe spraakoproep ontvangen. Als u het aanvaardt, schakelt de audio over naar spraakcommunicatie."),
("texture_render_tip", "Pas textuurrendering toe om afbeeldingen vloeiender te maken."),
("Use texture rendering", "Textuurrendering gebruiken"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Получен новый запрос на голосовой вызов. Если вы его примите, звук переключится на голосовую связь."),
("texture_render_tip", "Использовать визуализацию текстур, чтобы сделать изображения более плавными."),
("Use texture rendering", "Визуализация текстур"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Bola prijatá nová žiadosť o hlasový hovor. Ak ho prijmete, zvuk sa prepne na hlasovú komunikáciu."),
("texture_render_tip", "Použiť vykresľovanie textúr, aby boli obrázky hladšie."),
("Use texture rendering", "Použiť vykresľovanie textúr"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "收到新的語音通話請求。如果您接受,音訊將切換為語音通訊。"),
("texture_render_tip", "使用紋理渲染,讓圖片更加順暢。 如果您遭遇渲染問題,可嘗試關閉此選項。"),
("Use texture rendering", "使用紋理渲染"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", "Отримано новий запит на голосовий дзвінок. Якщо ви приймете його, аудіо перемкнеться на голосовий звʼязок."),
("texture_render_tip", "Використовувати візуалізацію текстур для покращення плавності зображень."),
("Use texture rendering", "Використовувати візуалізацію текстур"),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}

View File

@ -615,5 +615,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("android_new_voice_call_tip", ""),
("texture_render_tip", ""),
("Use texture rendering", ""),
("Floating window", ""),
("floating_window_tip", ""),
].iter().cloned().collect();
}