Compare commits

...

22 commits

Author SHA1 Message Date
Gaurav Ujjwal
698f01aacd Allow GitHub Actions to run on any push
Some checks are pending
Android CI / build (push) Waiting to run
2022-10-04 23:00:37 +05:30
Gaurav Ujjwal
09a4990433 Guard against null events passed to onScroll
It appears that on some devices, e1 can be null, which would result in a
crash. This is probably due to manufacturers messing with input handling
of AOSP.
2022-10-04 23:00:37 +05:30
Felix Yan
1fe3dedc52
Correct typos in app/CMakeLists.txt (#90) 2022-08-22 20:13:18 +05:30
Gaurav Ujjwal
ad6d081a6f Allow client-side cursor movement in view-only mode
With direct-touch off, panning the viewer requires cursor movement.
GitHub Issue: #89
2022-08-16 13:27:26 +05:30
Gaurav Ujjwal
64f06caa09 Improve two-finger-swipe vs scale detection 2022-08-15 23:17:10 +05:30
Gaurav Ujjwal
ead089fd5e Release v1.9.2 2022-08-08 20:41:00 +05:30
Gaurav Ujjwal
548e0241a4 Translations update from Hosted Weblate
* Translated using Weblate (Polish)
* Translated using Weblate (Chinese (Simplified))

Co-authored-by: WaldiS <sto@tutanota.de>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
2022-08-08 20:23:04 +05:30
Gaurav Ujjwal
2ccbd0cbd8 Fix possible crash on opening the toolbar for the first time
AVNC always tried to open the left/start drawer when connecting for the
first time, to highlight it for the new users. But if a user changes the
toolbar alignment to 'End' before ever connecting to a server, AVNC will
crash when connecting for the first time, because there won't be any
'left' drawer.

Fix it by opening the toolbar directly.
2022-08-08 20:23:04 +05:30
Gaurav Ujjwal
bf73d24f9e Constrain aspect ratio of PiP window
Android requires the aspect ratio of PiP window to be within 1:2.39 range
in either orientation. If  aspect ratio of framebuffer was outside this
range, it would crash the app.

Also guarded against unlikely possibility of fbWidth/fbHeight being 0.
2022-08-02 16:50:03 +05:30
Gaurav Ujjwal
ee8ae23d5f Refactor connection initialization
Until now, connection was started at the very end of onCreate(). As a
result components like Dispatcher could not rely on VncViewModel's
profile during their initialization. Now initialization happen at
the beginning.

It also comes with a tiny bit of performance improvement.
Receiver thread can now start the connection early, while main thread
is still creating the UI.
2022-07-31 22:38:04 +05:30
Gaurav Ujjwal
a28149eb99 Fix default value for mouse back button preference 2022-07-31 12:06:20 +05:30
Gaurav Ujjwal
2abfd14d83 Remove temporary message about Hide Cursor option 2022-07-29 13:59:11 +05:30
Gaurav Ujjwal
31c90b4287 Release v1.9.1 2022-07-24 16:05:36 +05:30
Gaurav Ujjwal
4facebf48e Use immersive mode pref for full edge exclusion from System Gestures
Current approach won't work because Android enforces a 200dp vertical
limit, unless app is in sticky immersive mode.
2022-07-24 15:09:35 +05:30
Weblate (bot)
153f69d12c
Translations update from Hosted Weblate (#88)
* Translated using Weblate (German)
* Translated using Weblate (Polish)
* Translated using Weblate (Portuguese (Brazil))
* Translated using Weblate (Ukrainian)
* Translated using Weblate (Russian)

Co-authored-by: Pure Incompetence <inc@mailbox.org>
Co-authored-by: WaldiS <sto@tutanota.de>
Co-authored-by: mezysinc <mezysinc@mailon.site>
Co-authored-by: Andrij Mizyk <andmiz@proton.me>
Co-authored-by: Gaurav Ujjwal <gujjwal00@gmail.com>
2022-07-24 15:01:01 +05:30
Gaurav Ujjwal
9c3a0cc3dd Switch 'Full immersive mode' preference's default value to true
In future versions this will be merged  into 'Fullscreen' pref, so
turning it on by default should give us time to figure out any issues.
2022-07-24 14:01:42 +05:30
Gaurav Ujjwal
08b4c01d99 Exclude connection toolbar area from system gestures on API 29+ 2022-07-24 13:43:35 +05:30
Gaurav Ujjwal
22b071365e Update wolfSSL submodule 2022-07-20 20:28:26 +05:30
Gaurav Ujjwal
c671615025 OpenGL: Set texture wrap mode to GL_CLAMP_TO_EDGE
In OpenGL ES 2, support for sampling non-power-of-two textures in
fragment shaders is only guaranteed when wrap mode is GL_CLAMP_TO_EDGE.
Although most modern GPUs don't enforce this requirement, some devices
(like Tegra from Nvidia) do.

Related Github Issue: #85
2022-07-15 23:22:54 +05:30
Gaurav Ujjwal
1af619551a OpenGL: Use correct type for position attribute in Vertex Shader
For a_Position attribute, Frame.bind() only assign the x,y components,
but a_Position was declared as vec4.

While this generally does not cause any issue, its much better to
use the correct data type to avoid any possible misbehavior.
2022-07-15 23:12:02 +05:30
Gaurav Ujjwal
3d82e80beb OpenGL: Move program valition to onDrawFrame()
Program validation verifies the shaders against current OpenGL state.
So doing it in onSurfaceCreated() is not helpful, because uniforms
& attributes are not set at that stage and texture is not properly
initialized.

Now program is validated just before the draw command is issued.
2022-07-15 22:59:55 +05:30
Gaurav Ujjwal
b3bd9399f0 [Style] Cleanup 2022-06-02 21:28:59 +05:30
31 changed files with 457 additions and 180 deletions

View file

@ -1,8 +1,6 @@
name: Android CI
on:
push:
branches: [ master ]
on: push
jobs:
build:

View file

@ -4,24 +4,6 @@
<JavaCodeStyleSettings>
<option name="JD_P_AT_EMPTY_LINES" value="false" />
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
</JetCodeStyleSettings>
<codeStyleSettings language="ObjectiveC">
<option name="RIGHT_MARGIN" value="120" />
<option name="SOFT_MARGINS" value="80,100" />

View file

@ -19,7 +19,7 @@ macro(avnc_check_submodule name)
endmacro()
# Requred to enable SIMD support on ARM
# Required to enable SIMD support on ARM
if (CMAKE_ANDROID_ARCH STREQUAL "arm64")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} --target=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}")
elseif (CMAKE_ANDROID_ARCH STREQUAL "arm")
@ -53,7 +53,7 @@ set(AVNC_LIBSSL_SRC_DIR ${AVNC_EXTERN_DIR}/wolfssl)
set(AVNC_LIBSSL_BUILD_DIR ${CMAKE_BINARY_DIR}/wolfssl)
# CMake support in wolfSSl is still under development, so we have to
# manully set some flags to enable OpenSSL compatibility layer
# manually set some flags to enable OpenSSL compatibility layer
set(WOLFSSL_CRL yes)
set(WOLFSSL_DES3 yes)
add_definitions(-DOPENSSL_ALL -DOPENSSL_EXTRA -DHAVE_CRL -DHAVE_EX_DATA

View file

@ -11,8 +11,8 @@ android {
applicationId "com.gaurav.avnc"
minSdkVersion 21
targetSdkVersion 30
versionCode 12
versionName "1.9.0"
versionCode 14
versionName "1.9.2"
javaCompileOptions {
annotationProcessorOptions {

View file

@ -9,7 +9,6 @@
package com.gaurav.avnc.ui.vnc
import android.content.Context
import android.content.Intent
import android.view.inputmethod.InputMethodManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onIdle
@ -36,8 +35,7 @@ class VncActivityTest {
testServer.start()
val profile = ServerProfile(host = testServer.host, port = testServer.port)
val intent = Intent(targetContext, VncActivity::class.java)
.putExtra("com.gaurav.avnc.server_profile", profile)
val intent = createVncIntent(targetContext, profile)
ActivityScenario.launch<VncActivity>(intent).use {
onView(withId(R.id.frame_view)).checkWillBeDisplayed() // Wait for connection

View file

@ -13,6 +13,9 @@ import android.os.Build
import android.view.*
import com.gaurav.avnc.viewmodel.VncViewModel
import com.gaurav.avnc.vnc.PointerButton
import kotlin.math.PI
import kotlin.math.abs
import kotlin.math.atan2
import kotlin.math.max
/**
@ -170,11 +173,13 @@ class TouchHandler(private val viewModel: VncViewModel, private val dispatcher:
private val gestureDetector = GestureDetector(viewModel.app, this)
private val multiFingerTapDetector = MultiFingerTapDetector()
private val dragDetector = DragDetector()
private val swipeVsScale = SwipeVsScale()
private val dragEnabled = viewModel.pref.input.gesture.dragEnabled
private val swipeSensitivity = viewModel.pref.input.gesture.swipeSensitivity
private fun handleGestureEvent(event: MotionEvent): Boolean {
swipeVsScale.onTouchEvent(event)
dragDetector.onTouchEvent(event)
multiFingerTapDetector.onTouchEvent(event)
scaleDetector.onTouchEvent(event)
@ -184,7 +189,8 @@ class TouchHandler(private val viewModel: VncViewModel, private val dispatcher:
override fun onScaleBegin(detector: ScaleGestureDetector) = true
override fun onScaleEnd(detector: ScaleGestureDetector) {}
override fun onScale(detector: ScaleGestureDetector): Boolean {
dispatcher.onScale(detector.scaleFactor, detector.focusX, detector.focusY)
if (swipeVsScale.shouldScale())
dispatcher.onScale(detector.scaleFactor, detector.focusX, detector.focusY)
return true
}
@ -214,15 +220,17 @@ class TouchHandler(private val viewModel: VncViewModel, private val dispatcher:
return true
}
override fun onScroll(e1: MotionEvent, e2: MotionEvent, dX: Float, dY: Float): Boolean {
val startPoint = e1.point()
override fun onScroll(e1: MotionEvent?, e2: MotionEvent, dX: Float, dY: Float): Boolean {
// As weird as it may be, e1 can be null on some devices
val startPoint = e1?.point() ?: return false
val currentPoint = e2.point()
val normalizedDx = -dX * swipeSensitivity
val normalizedDy = -dY * swipeSensitivity
when (e2.pointerCount) {
1 -> dispatcher.onSwipe1(startPoint, currentPoint, normalizedDx, normalizedDy)
2 -> dispatcher.onSwipe2(startPoint, currentPoint, normalizedDx, normalizedDy)
2 -> if (swipeVsScale.shouldSwipe())
dispatcher.onSwipe2(startPoint, currentPoint, normalizedDx, normalizedDy)
}
multiFingerTapDetector.reset()
@ -342,4 +350,106 @@ class TouchHandler(private val viewModel: VncViewModel, private val dispatcher:
fingerCount = 0
}
}
/**
* Swipe vs Scale detector.
*
* Many two-finger gestures are detected as both swipe & scale gestures because
* [GestureDetector] & [ScaleGestureDetector] work independently. This works
* very well when two-finger swipe pref is set to 'pan' (default value).
* But when the pref is set to 'remote-scroll', this independent detection
* becomes an issue. When user tries to scale, it frequently triggers remote
* scrolling. And when user tries to scroll, it triggers scaling.
*
* This class tries to clearly differentiate between these two gestures.
* It works by tracking the fingers, and calculating the angle between two paths.
* Then [decide] between two gestures by comparing the angle to some thresholds.
*
* This class can mis-detect some gestures because fingers don't always move
* perfectly, but it does provide huge improvement over existing situation.
*/
private inner class SwipeVsScale {
private val enabled = viewModel.pref.input.gesture.swipe2 == "remote-scroll"
private var detecting = false
private var scaleDetected = false
private var swipeDetected = false
private var f1Id = 0 // Finger 1
private var f2Id = 0 // Finger 2
private val f1Start = PointF()
private val f2Start = PointF()
private val f1Current = PointF()
private val f2Current = PointF()
fun onTouchEvent(e: MotionEvent) {
if (!enabled)
return
when (e.actionMasked) {
MotionEvent.ACTION_DOWN,
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_UP,
MotionEvent.ACTION_POINTER_UP -> {
detecting = false
scaleDetected = false
swipeDetected = false
}
MotionEvent.ACTION_POINTER_DOWN -> {
detecting = e.pointerCount == 2
if (detecting) {
f1Id = e.getPointerId(0)
f2Id = e.getPointerId(1)
f1Start.set(e.getX(f1Id), e.getY(f1Id))
f2Start.set(e.getX(f2Id), e.getY(f2Id))
f1Current.set(f1Start)
f2Current.set(f2Start)
}
}
MotionEvent.ACTION_MOVE -> {
if (detecting) {
f1Current.set(e.getX(f1Id), e.getY(f1Id))
f2Current.set(e.getX(f2Id), e.getY(f2Id))
}
}
}
}
fun shouldScale(): Boolean {
decide()
return !enabled || (detecting && scaleDetected)
}
fun shouldSwipe(): Boolean {
decide()
return !enabled || (detecting && swipeDetected)
}
/**
* Decides if gesture can be considered a swipe/scale
*/
private fun decide() {
if (!detecting)
return
val t1 = theta(f1Start, f1Current)
val t2 = theta(f2Start, f2Current)
val diff = abs(t1 - t2)
scaleDetected = diff > 45
swipeDetected = diff < 30
}
/**
* Returns the angle made by line [p1]->[p2] with the positive x-axis.
* Returned angle will be in range [0, 360]
*/
private fun theta(p1: PointF, p2: PointF): Double {
val theta = atan2(p2.y - p1.y, p2.x - p1.x)
val degree = (theta / PI) * 180
return (degree + 360) % 360 // Map [-180, 180] to [0, 360]
}
}
}

View file

@ -41,10 +41,14 @@ import java.lang.ref.WeakReference
private const val PROFILE_KEY = "com.gaurav.avnc.server_profile"
fun createVncIntent(context: Context, profile: ServerProfile): Intent {
return Intent(context, VncActivity::class.java).apply {
putExtra(PROFILE_KEY, profile)
}
}
fun startVncActivity(source: Activity, profile: ServerProfile) {
val intent = Intent(source, VncActivity::class.java)
intent.putExtra(PROFILE_KEY, profile)
source.startActivity(intent)
source.startActivity(createVncIntent(source, profile))
}
fun startVncActivity(source: Activity, uri: VncUri) {
@ -59,7 +63,7 @@ fun startVncActivity(source: Activity, uri: VncUri) {
*/
class VncActivity : AppCompatActivity() {
private val profile by lazy { loadProfile() }
private lateinit var profile: ServerProfile
val viewModel by viewModels<VncViewModel>()
lateinit var binding: ActivityVncBinding
private val dispatcher by lazy { Dispatcher(this) }
@ -69,27 +73,29 @@ class VncActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
profile = loadProfile()
viewModel.initConnection(profile)
//Main UI
binding = DataBindingUtil.setContentView(this, R.layout.activity_vnc)
binding.viewModel = viewModel
binding.lifecycleOwner = this
binding.frameView.initialize(this)
viewModel.frameViewRef = WeakReference(binding.frameView)
setupLayout()
binding.frameView.initialize(this)
binding.retryConnectionBtn.setOnClickListener { retryConnection() }
//Drawers
setupDrawerLayout()
//Buttons
binding.keyboardBtn.setOnClickListener { showKeyboard(); closeDrawers() }
binding.zoomResetBtn.setOnClickListener { viewModel.resetZoom(); closeDrawers() }
binding.virtualKeysBtn.setOnClickListener { virtualKeys.show(); closeDrawers() }
binding.retryConnectionBtn.setOnClickListener { retryConnection() }
//ViewModel setup
viewModel.frameViewRef = WeakReference(binding.frameView)
//Observers
viewModel.credentialRequest.observe(this) { showCredentialDialog() }
viewModel.sshHostKeyVerifyRequest.observe(this) { showHostKeyDialog() }
viewModel.state.observe(this) { onClientStateChanged(it) }
viewModel.initConnection(profile) //Should be called after observers has been setup
}
override fun onResume() {
@ -116,14 +122,11 @@ class VncActivity : AppCompatActivity() {
private fun loadProfile(): ServerProfile {
val profile = intent.getParcelableExtra<ServerProfile>(PROFILE_KEY)
if (profile != null) {
// Make a copy to avoid modifying intent's instance,
// because we may need the original if we have to retry connection.
return profile.copy()
}
check(profile != null) { "ServerProfile is missing from VncActivity Intent" }
Log.e(javaClass.simpleName, "No connection information was passed through Intent.")
return ServerProfile()
// Make a copy to avoid modifying intent's instance,
// because we may need the original if we have to retry connection.
return profile.copy()
}
private fun retryConnection() {
@ -161,10 +164,10 @@ class VncActivity : AppCompatActivity() {
viewModel.pref.runInfo.hasConnectedSuccessfully = true
// Highlight drawer for first time users
binding.drawerLayout.open()
binding.drawerLayout.openDrawer(binding.primaryToolbar)
lifecycleScope.launchWhenCreated {
delay(1500)
binding.drawerLayout.close()
binding.drawerLayout.closeDrawer(binding.primaryToolbar)
}
}
@ -246,6 +249,25 @@ class VncActivity : AppCompatActivity() {
if (viewModel.pref.experimental.swipeCloseToolbar)
Experimental.setupDrawerCloseOnScrimSwipe(binding.drawerLayout, gravityH)
//Add System Gesture exclusion rects to allow opening toolbar drawer by swiping from edge
if (Build.VERSION.SDK_INT >= 29) {
binding.primaryToolbar.addOnLayoutChangeListener { _, left, top, right, bottom, _, _, _, _ ->
val root = binding.drawerLayout
val rect = Rect(left, top, right, bottom)
if (left < 0) rect.offset(-left, 0)
if (right > root.width) rect.offset(-(right - root.width), 0)
if (immersiveMode) {
rect.top = 0
rect.bottom = root.height
}
//Set exclusion rects on root because toolbar may not be visible
root.systemGestureExclusionRects = listOf(rect)
}
}
}
@ -297,8 +319,14 @@ class VncActivity : AppCompatActivity() {
if (canEnter && Build.VERSION.SDK_INT >= 26) {
val fs = viewModel.frameState
val aspectRatio = Rational(fs.fbWidth.toInt(), fs.fbHeight.toInt())
var w = viewModel.frameState.fbWidth
var h = viewModel.frameState.fbHeight
// Android require aspect ratio to be less than 2.39
w = w.coerceIn(1f, 2.3f * h)
h = h.coerceIn(1f, 2.3f * w)
val aspectRatio = Rational(w.toInt(), h.toInt())
val param = PictureInPictureParams.Builder().setAspectRatio(aspectRatio).build()
try {

View file

@ -10,6 +10,7 @@ package com.gaurav.avnc.ui.vnc.gl
import android.opengl.GLES20.*
import android.util.Log
import com.gaurav.avnc.BuildConfig
/**
* Represents the GL program used for Frame rendering.
@ -34,6 +35,7 @@ class FrameProgram {
val uProjectionLocation = glGetUniformLocation(program, U_PROJECTION)
val uTexUnitLocation = glGetUniformLocation(program, U_TEXTURE_UNIT)
val textureId = createTexture()
var validated = false
fun setUniforms(projectionMatrix: FloatArray) {
@ -54,10 +56,19 @@ class FrameProgram {
glBindTexture(GL_TEXTURE_2D, texturesObjects[0])
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glBindTexture(GL_TEXTURE_2D, 0)
return texturesObjects[0]
}
fun validate() {
if (BuildConfig.DEBUG && !validated) {
ShaderCompiler.validateProgram(program)
validated = true
}
}
fun useProgram() {
glUseProgram(program)
}

View file

@ -91,6 +91,8 @@ class Renderer(val viewModel: VncViewModel) : GLSurfaceView.Renderer {
frame.updateFbSize(state.fbWidth, state.fbHeight)
frame.bind(program)
program.validate()
frame.draw()
}
}

View file

@ -10,7 +10,6 @@ package com.gaurav.avnc.ui.vnc.gl
import android.opengl.GLES20.*
import android.util.Log
import com.gaurav.avnc.BuildConfig
object ShaderCompiler {
@ -76,9 +75,6 @@ object ShaderCompiler {
if (vertexShaderId == 0 || fragmentShaderId == 0)
return 0
val programId = linkProgram(vertexShaderId, fragmentShaderId)
if (BuildConfig.DEBUG)
validateProgram(programId)
return programId
return linkProgram(vertexShaderId, fragmentShaderId)
}
}

View file

@ -15,13 +15,13 @@ object Shaders {
//language=GLSL
const val VERTEX_SHADER = """
uniform mat4 u_Projection;
attribute vec4 a_Position;
attribute vec2 a_Position;
attribute vec2 a_TextureCoordinates;
varying vec2 v_TextureCoordinates;
void main()
{
v_TextureCoordinates = a_TextureCoordinates;
gl_Position = u_Projection * a_Position;
gl_Position = u_Projection * vec4(a_Position, 0, 1);
}"""
//language=GLSL

View file

@ -75,7 +75,7 @@ class AppPreferences(context: Context) {
inner class Experimental {
val swipeCloseToolbar; get() = prefs.getBoolean("experimental_vnc_toolbar_swipe_close", true)
val immersiveMode; get() = prefs.getBoolean("viewer_immersive_mode", false)
val immersiveMode; get() = prefs.getBoolean("viewer_immersive_mode", true)
}
/**

View file

@ -92,7 +92,7 @@ class VncViewModel(app: Application) : BaseViewModel(app), VncClient.Observer {
/**
* [ServerProfile] used for current connection.
*/
var profile = ServerProfile()
var profile = ServerProfile(); private set
/**
* We have two places for connection state (both are synced):
@ -167,16 +167,14 @@ class VncViewModel(app: Application) : BaseViewModel(app), VncClient.Observer {
/**
* Initialize VNC connection using given profile.
* [initConnection] can be called multiple times due to activity restarts.
* It may be called multiple times due to activity restarts.
*/
fun initConnection(profile: ServerProfile) {
if (state.value != State.Created)
return
this.profile = profile
state.value = State.Connecting
launchConnection()
if (state.value == State.Created) {
state.value = State.Connecting
this.profile = profile
launchConnection()
}
}
private fun launchConnection() {

View file

@ -171,7 +171,7 @@ class VncClient(private val observer: Observer) {
* @param x Horizontal pointer coordinate
* @param y Vertical pointer coordinate
*/
fun moveClientPointer(x: Int, y: Int) = executeSend {
fun moveClientPointer(x: Int, y: Int) {
pointerX = x
pointerY = y
observer.onPointerMoved(x, y)

View file

@ -144,19 +144,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/use_repeater" />
<!--Temporary message about moved option-->
<TextView
android:id="@+id/use_local_cursor"
style="@style/FormField.EditText"
android:drawablePadding="@dimen/padding_normal"
android:paddingStart="@dimen/padding_small"
android:paddingTop="0dp"
android:text="@string/msg_hide_remote_pointer_option_moved"
app:drawableStartCompat="@drawable/ic_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/view_only" />
<!--Key Compatibility mode-->
<CheckBox
android:id="@+id/key_compat_mode"
@ -165,7 +152,7 @@
android:text="@string/title_key_compat_mode"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/use_local_cursor" />
app:layout_constraintTop_toBottomOf="@id/view_only" />
<ImageButton
android:id="@+id/key_compat_mode_help_btn"

View file

@ -34,8 +34,6 @@
<string name="msg_invalid_vnc_uri">Ungültige VNC-URI</string>
<string name="msg_copied_to_clipboard">Kopiert</string>
<string name="msg_key_compat_mode_help">Einige Server unterstützen Unicode-Zeichen nur teilweise. Legacy key events kann die Eingabe von nicht-englischem Text ermöglichen.</string>
<string name="msg_hide_remote_pointer_option_moved">\'Ausblenden des entfernten Mauszeigers\' ist jetzt verfügbar unter
\n\'Einstellungen → Eingabe → Maus\'</string>
<string name="tip_empty_server_list">Die Serverliste ist leer.
\nDrücke \'<b>+</b>\', um einen Server hinzuzufügen, oder
\nnutze die Adresszeile oben, um direkt eine Verbindung aufzubauen.</string>
@ -70,7 +68,7 @@
<string name="pref_sort_server_list">Sortiere die gespeicherten Server nach ihren Namen</string>
<string name="pref_gesture">Gesten</string>
<string name="pref_swipe2">Wischen mit zwei Fingern</string>
<string name="pref_drag">Ziehen (gedrückt halten und wischen)</string>
<string name="pref_drag">Ziehen (Drag and Drop)</string>
<string name="pref_mouse_passthrough">Maus-Passthrough</string>
<string name="pref_mouse_passthrough_summary_off">Maus-Bewegungen für lokale Gesten verwenden</string>
<string name="pref_hide_local_cursor">Lokalen Mauszeiger verstecken</string>
@ -170,4 +168,12 @@
<string name="pref_direct_touch">Direkte Touch-Umsetzung auf dem Server</string>
<string name="pref_direct_touch_summary_on">Setze Aktionen direkt am Ort des Tippens um</string>
<string name="pref_direct_touch_summary_off">Setze Aktionen an einem Mauszeiger um, ähnlich einem Touchpad</string>
<string name="pref_orientation">Bildschirmausrichtung</string>
<string name="pref_orientation_option_auto">Automatisch (nach Lagesensor)</string>
<string name="pref_orientation_option_portrait">Hochformat</string>
<string name="pref_orientation_option_landscape">Querformat</string>
<string name="msg_drag_gesture_help">Der Ziehgeste eine Aktion zuzuweisen, wird die Erkennung von langem Drücken ändern:
\n
\n<b>Drücken-Halten-Loslassen</b> → Lange drücken
\n<b>Drücken-Halten-Wischen</b> → Drag and Drop</string>
</resources>

View file

@ -176,6 +176,4 @@
<string name="desc_discovery_stop_btn">اکتشاف کارسازها را متوقّف کن</string>
<string name="pref_discovery_autorun_summary">در حالی که در صفحهٔ اصلی هستید، کارسازها را کشف کنید</string>
<string name="title_default_security">امنیت پیش‌گزیده</string>
<string name="msg_hide_remote_pointer_option_moved">«پنهان کردن اشاره‌گر دوردست» حالا در مسیر
\n«تنظیمات ← ورودی ← ماوس» در دسترس است</string>
</resources>

View file

@ -167,8 +167,6 @@
<string name="pref_mouse_back_action_middle">Clic molette</string>
<string name="pref_mouse_back_action_right">Clic droit</string>
<string name="title_default_security">Sécurité par défaut</string>
<string name="msg_hide_remote_pointer_option_moved">« Masquer le pointeur distant » est désormais disponible dans
\n« Paramètres → Saisie → Souris »</string>
<string name="pref_swipe_sensitivity">Sensibilité du défilement</string>
<string name="msg_drag_gesture_help">L\'affectation d\'une action à un geste de glissement modifiera la détection de l\'appui long :
\n

View file

@ -167,7 +167,5 @@
<string name="pref_mouse_back_action_right">Høyreklikk</string>
<string name="pref_mouse_back_action_middle">Midt-klikk</string>
<string name="title_default_security">Forvalgt sikkerhet</string>
<string name="msg_hide_remote_pointer_option_moved">«Skjul fjernpeker» er nå tilgjengelig i
\n«Innstillinger → Inndata → Mus»</string>
<string name="pref_swipe_sensitivity">Dragningssensitivitet</string>
</resources>

View file

@ -141,8 +141,6 @@
<string name="desc_back_btn">Wstecz</string>
<string name="pref_mouse_passthrough">Przekazywanie myszy</string>
<string name="pref_mouse_passthrough_summary_off">Używanie zdarzeń myszy do wykonywania gestów lokalnych</string>
<string name="msg_hide_remote_pointer_option_moved">Opcja „Ukryj zdalny wskaźnik” jest teraz dostępna w
\n„Ustawienia → Wejście → Mysz”</string>
<string name="pref_gesture_action_remote_scroll">Przewiń zdalną zawartość</string>
<string name="pref_mouse_back_action_middle">Kliknij środkowym przyciskiem</string>
<string name="pref_vk_show_all">Pokaż wszystkie klawisze</string>
@ -174,4 +172,6 @@
<string name="pref_orientation_option_auto">Automatycznie</string>
<string name="pref_orientation_option_portrait">Portret</string>
<string name="pref_orientation_option_landscape">Krajobraz</string>
<string name="desc_discovery_btn">Odnajduj serwery</string>
<string name="msg_export_auth_required">Uwierzytelnij się, aby eksportować serwery</string>
</resources>

View file

@ -6,11 +6,11 @@
~
~ See COPYING.txt for more details.
--><resources>
<string name="title_add_server_profile">Adicionar um servidor</string>
<string name="title_edit_server_profile">Edição do servidor</string>
<string name="title_add_server_profile">Adicionar servidor</string>
<string name="title_edit_server_profile">Editar servidor</string>
<string name="title_duplicate">Duplicar</string>
<string name="title_edit">Editar</string>
<string name="title_delete">Excluir</string>
<string name="title_delete">Apagar</string>
<string name="title_copy_host">Copiar host</string>
<string name="title_copy_name">Copiar nome</string>
<string name="title_advanced">Avançado</string>
@ -18,27 +18,27 @@
<string name="title_save">Salvar</string>
<string name="title_undo">Desfazer</string>
<string name="title_settings">Configurações</string>
<string name="title_credentials_required">Credenciais necessárias</string>
<string name="title_remember">Lembrar</string>
<string name="title_credentials_required">Autenticação</string>
<string name="title_remember">Salvar</string>
<string name="title_export">Exportar</string>
<string name="title_import">Importar</string>
<string name="title_view_only_mode">Modo somente de visualização</string>
<string name="title_hide_remote_cursor">Esconder cursor remoto</string>
<string name="title_key_compat_mode">Modo de compatibilidade do teclado</string>
<string name="title_use_ssh_tunnel">Usar túnel de SSH</string>
<string name="title_unknown_ssh_host">Host de SSH desconhecido</string>
<string name="title_ssh_host_key_changed">A chave do host foi alterada</string>
<string name="title_view_only_mode">Somente visualização</string>
<string name="title_hide_remote_cursor">Esconder ponteiro remoto</string>
<string name="title_key_compat_mode">Enviar eventos de teclado compatíveis</string>
<string name="title_use_ssh_tunnel">Usar túnel SSH</string>
<string name="title_unknown_ssh_host">Host SSH desconhecido</string>
<string name="title_ssh_host_key_changed">Chave do host de SSH mudou</string>
<string name="title_continue">Continuar</string>
<string name="title_delete_servers_before_import">Excluir os servidores atuais antes de importar</string>
<string name="title_delete_servers_before_import">Apagar os servidores atuais antes de importar</string>
<string name="title_password">Senha</string>
<string name="title_use_repeater">Usar repetidor</string>
<string name="title_private_key">Chave privada</string>
<string name="title_change">Alterar</string>
<string name="title_change">Mudar</string>
<string name="title_about">Sobre</string>
<string name="title_license">Licença</string>
<string name="title_open_source_libraries">Bibliotecas de código livre</string>
<string name="title_report_bug">Relatar um erro</string>
<string name="title_github_repo">Repositório no Github</string>
<string name="title_report_bug">Relatar um problema</string>
<string name="title_github_repo">Código fonte</string>
<string name="hint_urlbar">Conectar ao servidor</string>
<string name="hint_server_name">Nome (ex. PC do trabalho)</string>
<string name="hint_host">Host</string>
@ -48,50 +48,56 @@
<string name="hint_username">Nome de usuário</string>
<string name="hint_password">Senha</string>
<string name="hint_key_password">Senha chave</string>
<string name="msg_about_app">O AVNC é um cliente VNC de software livre para Android. Permite o controle remoto de qualquer dispositivo que executa um servidor VNC.</string>
<string name="msg_about_app">Um cliente VNC rápido e seguro. Permite visualizar e controlar remotamente qualquer dispositivo que executa um servidor VNC.
\n
\n
\nO AVNC é de código aberto e sob licença copyleft — feito com a ajuda de muitos colaboradores.</string>
<string name="msg_server_profile_added">Servidor adicionado</string>
<string name="msg_server_profile_deleted">Servidor excluído</string>
<string name="msg_pip_not_supported">O recurso de Picture-in-Picture não é suportado neste dispositivo</string>
<string name="msg_loading">Carregando …</string>
<string name="msg_imported">Importado com sucesso</string>
<string name="msg_exported">Exportado com sucesso</string>
<string name="msg_export_auth_required">É necessária a autenticação antes de exportar</string>
<string name="msg_server_profile_deleted">Servidor apagado</string>
<string name="msg_pip_not_supported">Não suportado neste dispositivo</string>
<string name="msg_loading">Carregando…</string>
<string name="msg_imported">Importado</string>
<string name="msg_exported">Exportado</string>
<string name="msg_export_auth_required">Autenticar primeiro para poder exportar servidores</string>
<string name="msg_export_auth_missing">Seu dispositivo não está seguro. Ative o bloqueio da tela para permitir a autenticação antes de exportar.</string>
<string name="msg_invalid_key_file">O arquivo não é uma chave privada válida</string>
<string name="msg_invalid_vnc_uri">O URI do VNC inválido</string>
<string name="msg_invalid_key_file">Arquivo de chave privada inválido</string>
<string name="msg_invalid_vnc_uri">A URI do VNC inválida</string>
<string name="msg_copied_to_clipboard">Copiado</string>
<string name="msg_key_compat_mode_help">Alguns servidores não tem suporte a entrada direta do Unicode. O modo de compatibilidade tenta enviar eventos chave em formato legado. \n\nTente ativar/desativar isto, se você estiver tendo problemas inserindo alguns caracteres.</string>
<string name="tip_empty_server_list">A lista de servidores está vazia.\nUse o botão \'<b>+</b>\' para adicionar um servidor, ou\nUse a barra do Url na parte superior para conectar-se diretamente a um servidor.</string>
<string name="tip_urlbar">Você pode digitar o nome de host ou endereço de IP.\n\'vnc://\' URIs também são suportados.</string>
<string name="tip_discovery">A descoberta pode encontrar automaticamente os servidores suportados\nexecutados na sua rede.</string>
<string name="msg_key_compat_mode_help">Alguns servidores têm suporte limitado ao Unicode. Os eventos de teclado legado podem ajudar a inserir texto não-inglês.</string>
<string name="tip_empty_server_list">A lista de servidores está vazia.
\nUse o botão \'<b>+</b>\' para adicionar um servidor, ou
\nuse a barra de endereço na área superior para conectar diretamente.</string>
<string name="tip_urlbar">Você pode digitar o endereço de IP, nome de host ou \'vnc://\' URI.</string>
<string name="tip_discovery">A descoberta pode automaticamente encontrar os servidores suportados
\nexecutados na sua rede.</string>
<!-- Accessibility descriptions -->
<string name="desc_navigation_btn">Abrir a aba de navegação</string>
<string name="desc_settings_btn">Abrir configurações</string>
<string name="desc_navigation_btn">Abrir aba de navegação</string>
<string name="desc_settings_btn">Configurações</string>
<string name="desc_saved_servers_tab">Servidores salvos</string>
<string name="desc_discovered_servers_tab">Servidores encontrados</string>
<string name="desc_add_new_server_btn">Adicionar um novo servidor</string>
<string name="desc_save_discovered_server_btn">Salvar este servidor</string>
<string name="desc_discovery_btn">Iniciar a descoberta de servidores</string>
<string name="desc_add_new_server_btn">Adicionar servidor</string>
<string name="desc_save_discovered_server_btn">Salvar</string>
<string name="desc_discovery_btn">Descobrir servidores</string>
<string name="desc_discovery_running">Descobrindo servidores na sua rede</string>
<string name="desc_keyboard_btn">Mostrar teclado</string>
<string name="desc_virtual_keys_btn">Mostrar teclas virtuais</string>
<string name="desc_reset_zoom_btn">Resetar o zoom para 100%</string>
<string name="desc_retry_connection_btn">Tente conectar novamente</string>
<string name="desc_reset_zoom_btn">Redefinir zoom</string>
<string name="desc_retry_connection_btn">Tente novamente</string>
<string name="desc_back_btn">Voltar</string>
<string name="desc_clear_url_btn">Remover a URL</string>
<string name="desc_server_url">Digite o endereço do servidor VNC</string>
<string name="desc_help_btn">Mostrar ajuda</string>
<string name="desc_discovered_list">Lista de servidores descobertos automaticamente</string>
<string name="desc_saved_servers_list">Lista de servidores salvos</string>
<string name="desc_clear_url_btn">Limpar</string>
<string name="desc_server_url">Endereço do servidor</string>
<string name="desc_help_btn">Ajuda</string>
<string name="desc_discovered_list">Lista dos servidores descobertos automaticamente</string>
<string name="desc_saved_servers_list">Lista dos servidores salvos</string>
<!-- Preference -->
<string name="pref_ui">Interface</string>
<string name="pref_ui_summary">Aspecto</string>
<string name="pref_viewer">Visualizador</string>
<string name="pref_viewer_summary">Picture-in-picture, zoom</string>
<string name="pref_viewer_summary">Imagem em popup, zoom</string>
<string name="pref_input">Entrada</string>
<string name="pref_input_summary">Gestos, mouse, teclas virtuais</string>
<string name="pref_servers">Servidores</string>
<string name="pref_server_summary">Descoberta, Credenciais</string>
<string name="pref_server_summary">Autenticação, descoberta</string>
<string name="pref_tools">Ferramentas</string>
<string name="pref_tools_summary">Importar/Exportar, depuração</string>
<string name="pref_experimental">Experimental</string>
@ -107,8 +113,8 @@
<string name="pref_gesture_action_remote_drag">Arrastar conteúdo remoto</string>
<string name="pref_gesture_action_open_keyboard">Mostrar teclado</string>
<string name="pref_theme">Tema</string>
<string name="pref_prefer_advanced_editor">Preferência do editor avançado</string>
<string name="pref_sort_server_list">Ordenar a lista de servidores</string>
<string name="pref_prefer_advanced_editor">Abrir diretamente opções avançadas de servidor</string>
<string name="pref_sort_server_list">Ordenar servidores salvos pelo nome</string>
<string name="pref_gesture">Gestos</string>
<string name="pref_single_tap">Toque único</string>
<string name="pref_two_finger_tap">Toque com 2 dedos</string>
@ -116,57 +122,66 @@
<string name="pref_long_press">Toque longo</string>
<string name="pref_swipe1">Deslize com 1 dedo</string>
<string name="pref_swipe2">Deslize com 2 dedos</string>
<string name="pref_drag">Arrastar (Toque longo depois deslizar)</string>
<string name="pref_drag">Arrastar</string>
<string name="pref_mouse">Mouse</string>
<string name="pref_mouse_passthrough">Passagem do mouse</string>
<string name="pref_mouse_passthrough_summary_off">Eventos do mouse são usados localmente para gestos</string>
<string name="pref_mouse_passthrough_summary_on">Eventos do mouse são enviados diretamente para servidor</string>
<string name="pref_mouse_passthrough_summary_off">Use eventos do mouse para gestos locais</string>
<string name="pref_mouse_passthrough_summary_on">Enviar eventos do mouse diretamente para servidor</string>
<string name="pref_vk">Teclas virtuais</string>
<string name="pref_vk_show_all">Mostrar todas teclas</string>
<string name="pref_vk_open_with_keyboard">Mostrar quando teclado está disponível</string>
<string name="pref_vk_open_with_keyboard">Abrir com teclado</string>
<string name="pref_km">Mapeamento de teclas</string>
<string name="pref_km_right_alt_to_super">Right Alt → Super</string>
<string name="pref_km_language_switch_to_super">Alteração de idioma → Super</string>
<string name="pref_km_back_to_escape">Voltar → Escape</string>
<string name="pref_km_back_to_escape_summary">A barra de navegação não é afetada por isto</string>
<string name="pref_fullscreen">Tela Cheia</string>
<string name="pref_enable_pip">Picture-in-picture</string>
<string name="pref_km_back_to_escape_summary">Não afeta a barra de navegação</string>
<string name="pref_fullscreen">Tela cheia</string>
<string name="pref_enable_pip">Imagem em popup</string>
<string name="pref_toolbar">Barra de ferramentas</string>
<string name="pref_toolbar_alignment">Alinhamento</string>
<string name="pref_zoom">Zoom</string>
<string name="pref_zoom_min">Zoom mínimo</string>
<string name="pref_zoom_max">Zoom máximo</string>
<string name="pref_clipboard_sync">Sincronização do Clipboard</string>
<string name="pref_credential">Credenciais</string>
<string name="pref_cred_autocomplete">Ativar preenchimento automático</string>
<string name="pref_cred_autocomplete_summary">Sugerir credenciais conhecidas ao conectar-se a um novo servidor</string>
<string name="pref_zoom_min">Mínimo</string>
<string name="pref_zoom_max">Máximo</string>
<string name="pref_clipboard_sync">Sincronização do clipboard</string>
<string name="pref_credential">Autenticação</string>
<string name="pref_cred_autocomplete">Preenchimento automático</string>
<string name="pref_cred_autocomplete_summary">Sugerir sessões salvas ao conectar para novos servidores</string>
<string name="pref_discovery">Descoberta</string>
<string name="pref_import_export">Importar/Exportar servidores</string>
<string name="pref_debugging">Depuração</string>
<string name="pref_logs">Registros</string>
<string name="pref_keycode_map">Mapa de códigos de teclado</string>
<string name="pref_experimental_toolbar_swipe_close">Deslizar para fechar a barra de ferramentas</string>
<string name="pref_experimental_toolbar_swipe_close_summary">Durante uma sessão remota, você pode deslizar para fechar a barra de ferramentas atualmente aberta</string>
<string name="pref_theme_option_system">Seguir Tema do Sistema</string>
<string name="pref_theme_option_dark">Modo Escuro</string>
<string name="pref_theme_option_light">Modo Claro</string>
<string name="pref_experimental_toolbar_swipe_close">Deslize para fechar a barra de ferramentas</string>
<string name="pref_experimental_toolbar_swipe_close_summary">Durante uma sessão remota, você pode deslizar para fechar a barra de ferramentas aberta neste momento</string>
<string name="pref_theme_option_system">Sistema</string>
<string name="pref_theme_option_dark">Escuro</string>
<string name="pref_theme_option_light">Claro</string>
<string name="pref_toolbar_alignment_option_start">Início</string>
<string name="pref_toolbar_alignment_option_end">Final</string>
<string name="pref_hide_local_cursor">Ocultar Cursor do Android</string>
<string name="pref_hide_local_cursor">Esconder ponteiro local</string>
<string name="title_clear">Limpar</string>
<string name="pref_experimental_immersive_mode">Modo totalmente imersivo</string>
<string name="pref_experimental_immersive_mode_summary">Oculta todas as barras do sistema em modo de tela cheia</string>
<string name="msg_ptr_hiding_not_supported">Ocultar cursor não é compatível com este dispositivo</string>
<string name="desc_discovery_stop_btn">Parar de descobrir servidores</string>
<string name="msg_ptr_hiding_not_supported">Não suportado neste dispositivo</string>
<string name="desc_discovery_stop_btn">Parar a descoberta de servidores</string>
<string name="pref_direct_touch_summary_off">Faça ações no ponteiro</string>
<string name="pref_mouse_back_action_default">Padrão</string>
<string name="pref_mouse_back_action_right">Clique com o botão direito</string>
<string name="pref_mouse_back">Botão \"voltar</string>
<string name="pref_mouse_back_action_middle">Clique do meio</string>
<string name="pref_mouse_back_action_right">Clique com botão direito</string>
<string name="pref_mouse_back">Botão Voltar</string>
<string name="pref_mouse_back_action_middle">Clique com botão do meio</string>
<string name="pref_discovery_autorun">Execução automática</string>
<string name="pref_discovery_autorun_summary">Descubra servidores enquanto estiver na página inicial</string>
<string name="pref_rediscovery_indicator">Destaque servidores redescobertos</string>
<string name="pref_direct_touch_summary_on">Faça ações no ponto de contato</string>
<string name="pref_direct_touch">Toque direto</string>
<string name="title_default_security">Segurança Padrão</string>
<string name="title_default_security">Segurança padrão</string>
<string name="msg_drag_gesture_help">Ao atribuir ação de gesto de Arrastar você mudará Detecção de toque longo:
\n
\n<b>Toque-segure-solte</b> → Toque longo
\n<b>Toque-segure-deslize</b> → Arrastar</string>
<string name="pref_swipe_sensitivity">Sensibilidade de deslize</string>
<string name="pref_orientation">Orientação da tela</string>
<string name="pref_orientation_option_auto">Automática</string>
<string name="pref_orientation_option_portrait">Vertical</string>
<string name="pref_orientation_option_landscape">Horizontal</string>
</resources>

View file

@ -1,2 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<resources />
<resources>
<string name="title_add_server_profile">Добавить сервер</string>
<string name="title_edit_server_profile">Изменить сервер</string>
<string name="title_duplicate">Создать копию</string>
<string name="title_edit">Изменить</string>
<string name="title_delete">Удалить</string>
<string name="title_cancel">Отменить</string>
<string name="title_save">Сохранить</string>
<string name="title_settings">Настройки</string>
<string name="title_credentials_required">Войти</string>
<string name="title_export">Экспорт</string>
<string name="title_import">Импорт</string>
<string name="title_view_only_mode">Только просмотр</string>
<string name="msg_invalid_key_file">недействительный файл приватного ключа</string>
<string name="pref_servers">Серверы</string>
<string name="pref_mouse">Мышь</string>
<string name="title_default_security">Безопасность по-умолчанию</string>
<string name="title_delete_servers_before_import">Удалите текущие серверы перед импортом</string>
<string name="title_password">Пароль</string>
<string name="title_change">Изменить</string>
<string name="title_about">О программе</string>
<string name="title_license">Лицензия</string>
<string name="title_open_source_libraries">Библиотеки с открытым исходным кодом</string>
<string name="title_github_repo">Исходный код</string>
<string name="hint_urlbar">Подключится к серверу</string>
<string name="hint_server_name">Имя (например: Рабочий ПК)</string>
<string name="hint_host">Хост</string>
<string name="hint_port">Порт</string>
<string name="hint_server_id">Идентификатор сервера</string>
<string name="msg_exported">Экспортировано</string>
<string name="msg_export_auth_missing">Ваше устройство не защищено. Включите блокировку экрана для обеспечения возможности аутентификации перед экспортом.</string>
<string name="msg_copied_to_clipboard">Скопировано</string>
<string name="desc_saved_servers_tab">Сохранённые серверы</string>
<string name="desc_discovered_servers_tab">Найденные серверы</string>
<string name="desc_discovery_btn">Найти серверы</string>
<string name="desc_discovery_running">Поиск серверов в вашей сети</string>
<string name="desc_virtual_keys_btn">Показать виртуальные клавиши</string>
<string name="desc_reset_zoom_btn">Сбросить масштабирование</string>
<string name="desc_back_btn">Назад</string>
<string name="desc_help_btn">Помощь</string>
<string name="desc_discovered_list">Список автоматически найденных серверов</string>
<string name="pref_ui_summary">Внешний вид</string>
<string name="desc_retry_connection_btn">Повторить</string>
<string name="pref_input">Ввод</string>
<string name="pref_input_summary">Жесты, мышь, виртуальные клавиши</string>
<string name="pref_server_summary">Вход, обнаружение</string>
<string name="pref_tools">Инструменты</string>
<string name="pref_tools_summary">Импорт/Экспорт, отладка</string>
<string name="pref_gesture_action_left_click">Левая кнопка мыши</string>
<string name="pref_gesture_action_middle_click">Средняя кнопка мыши</string>
<string name="pref_gesture_action_remote_scroll">Прокручивать удалённое содержимое</string>
<string name="pref_theme_option_system">Система</string>
<string name="pref_gesture">Жесты</string>
<string name="pref_double_tap">Двойное нажатие</string>
<string name="pref_sort_server_list">Сортировать сохранённые серверы по имени</string>
<string name="pref_single_tap">Одиночное нажатие</string>
<string name="pref_discovery">Обнаружение</string>
<string name="pref_discovery_autorun">Автозапуск</string>
<string name="pref_experimental_toolbar_swipe_close_summary">Во время удалённой сессии, вы можете сделать свайп для закрытия открытой панели инструментов</string>
<string name="pref_gesture_action_none">Нет</string>
<string name="pref_gesture_action_right_click">Правая кнопка мыши</string>
<string name="pref_gesture_action_double_click">Двойное нажатие</string>
<string name="pref_vk_show_all">Показать все клавиши</string>
<string name="pref_vk_open_with_keyboard">Открыть с клавиатурой</string>
<string name="pref_km_language_switch_to_super">Переключение раскладки → Super</string>
<string name="pref_toolbar_alignment_option_start">Начало</string>
<string name="pref_toolbar">Панель инструментов</string>
<string name="pref_toolbar_alignment_option_end">Конец</string>
<string name="pref_zoom">Масштабирование</string>
<string name="pref_import_export">Импортировать/Экспортировать серверы</string>
<string name="pref_debugging">Отладка</string>
<string name="title_report_bug">Сообщить об ошибке</string>
<string name="msg_pip_not_supported">Не поддерживается на этом устройстве</string>
<string name="msg_ptr_hiding_not_supported">Не поддерживается на этом устройстве</string>
<string name="msg_loading">Загрузка…</string>
<string name="msg_imported">Импортировано</string>
<string name="tip_urlbar">Вы можете ввести IP адрес, имя хоста, или \'vnc://\' URI.</string>
<string name="desc_add_new_server_btn">Добавить сервер</string>
<string name="desc_save_discovered_server_btn">Сохранить</string>
<string name="desc_discovery_stop_btn">остановить поиск серверов</string>
<string name="desc_keyboard_btn">Открыть клавиатуру</string>
<string name="desc_clear_url_btn">Очистить</string>
<string name="desc_server_url">Адрес сервера</string>
<string name="pref_viewer">Просмотр</string>
<string name="pref_viewer_summary">Картинка-в-картинке, масштабирование</string>
<string name="pref_experimental">Экспериментальные</string>
<string name="pref_experimental_summary">Экспериментальные возможности</string>
<string name="pref_gesture_action_move_pointer">Движение курсора</string>
<string name="pref_gesture_action_remote_drag">Перетаскивать удалённое содержимое</string>
<string name="pref_gesture_action_open_keyboard">Открыть клавиатуру</string>
<string name="pref_theme_option_dark">Тёмная</string>
<string name="pref_theme_option_light">Светлая</string>
<string name="pref_prefer_advanced_editor">Напрямую открывать дополнительные настройки сервера</string>
<string name="pref_long_press">Длительное нажатие</string>
<string name="pref_swipe1">Свайп одним пальцем</string>
<string name="pref_swipe2">Свайп двумя пальцами</string>
<string name="pref_drag">Перетаскивание</string>
<string name="pref_swipe_sensitivity">Чувствительность свайпа</string>
<string name="pref_hide_local_cursor">Скрыть локальный курсор</string>
<string name="pref_mouse_back">Кнопка \"назад\"</string>
<string name="pref_mouse_back_action_default">По-умолчанию</string>
<string name="pref_mouse_back_action_right">Правая кнопка мыши</string>
<string name="pref_mouse_back_action_middle">Средняя кнопка мыши</string>
<string name="pref_vk">Виртуальные клавиши</string>
<string name="pref_km_right_alt_to_super">Правый Alt → Super</string>
<string name="pref_zoom_min">Минимум</string>
<string name="pref_cred_autocomplete">Авто-завершение</string>
<string name="pref_zoom_max">Максимум</string>
<string name="pref_orientation">Ориентация экрана</string>
<string name="pref_orientation_option_auto">Автоматически</string>
<string name="pref_orientation_option_portrait">Портретная</string>
<string name="title_clear">Очистить</string>
<string name="msg_server_profile_added">Сервер добавлен</string>
<string name="msg_server_profile_deleted">Сервер удалён</string>
<string name="pref_ui">Интерфейс</string>
<string name="title_copy_host">Скопировать хост</string>
<string name="title_use_ssh_tunnel">Использовать SSH туннель</string>
<string name="title_unknown_ssh_host">Неизвестный SSH хост</string>
<string name="title_ssh_host_key_changed">Ключ хоста SSH изменён</string>
<string name="msg_about_app">Быстрый и защищённый VNC клиент. Удалённо просматривайте и управляйте любым устройством на котором запущен VNC сервер.
\n
\n
\nAVNC это программное обеспечение с открытым исходным кодом - созданное при поддержке от большого количества участников.</string>
<string name="tip_empty_server_list">Список серверов пуст.
\nНажмите \'<b>+</b>\' для добавления сервера, или
\nиспользуйте верхнюю адресную строку для прямого подключения.</string>
<string name="pref_two_finger_tap">Нажатие двумя пальцами</string>
<string name="pref_enable_pip">Картинка-в-картинке</string>
<string name="title_copy_name">Скопировать имя</string>
<string name="pref_logs">Логи</string>
<string name="title_hide_remote_cursor">Скрыть удалённый курсор</string>
<string name="title_continue">Продолжить</string>
<string name="hint_username">Имя пользователя</string>
<string name="desc_settings_btn">Настройки</string>
<string name="desc_saved_servers_list">Список сохранённых серверов</string>
<string name="hint_password">Пароль</string>
<string name="pref_theme">Тема</string>
<string name="pref_km">Назначения клавиш</string>
<string name="pref_orientation_option_landscape">Ландшафтная</string>
<string name="pref_fullscreen">Полноэкранный режим</string>
<string name="pref_clipboard_sync">Синхронизация буфера обмена</string>
<string name="pref_credential">Вход</string>
<string name="pref_experimental_immersive_mode">Режим полного присутствия</string>
<string name="pref_experimental_immersive_mode_summary">Скрывает все системные панели в полноэкранном режиме</string>
</resources>

View file

@ -168,8 +168,6 @@
<string name="pref_mouse_back_action_default">Öntanımlı</string>
<string name="pref_swipe_sensitivity">Kaydırma hassasiyeti</string>
<string name="title_default_security">Öntanımlı güvenlik</string>
<string name="msg_hide_remote_pointer_option_moved">\'Uzak işaretçiyi gizle\' artık şurada bulunabilir:
\n\'Ayarlar → Giriş → Fare\'</string>
<string name="msg_drag_gesture_help">Sürükleme hareketine bir eylem atamak, Uzun basma algılamasını değiştirecektir:
\n
\n<b>Basılı tut ve bırak</b> → Uzun bas

View file

@ -59,7 +59,7 @@
<string name="pref_experimental_summary">Додаткові можливості</string>
<string name="pref_gesture_action_left_click">Ліве клацання</string>
<string name="pref_gesture_action_move_pointer">Перемістити вказівник</string>
<string name="pref_clipboard_sync">Синхронувати буфери обміну</string>
<string name="pref_clipboard_sync">Синхронізувати буфери обміну</string>
<string name="pref_gesture_action_remote_scroll">Прокрутити віддалений вміст</string>
<string name="pref_km_language_switch_to_super">Перемикання мови → Super</string>
<string name="pref_toolbar_alignment_option_start">Початок</string>
@ -168,8 +168,6 @@
<string name="pref_mouse_back_action_middle">Клацання середньою кнопкою</string>
<string name="pref_swipe_sensitivity">Чутливість ковзання</string>
<string name="title_default_security">Типовий захист</string>
<string name="msg_hide_remote_pointer_option_moved">\'Ховати віддалений вказівник\' тепер доступне в
\n\'Налаштування → Введення → Миша\'</string>
<string name="msg_drag_gesture_help">Присвоєння дії жесту Перетягування змінить виявлення довгого натискання:
\n
\n<b>Натиснути-утримувати-відпустити</b> → Довге натискання
@ -177,4 +175,5 @@
<string name="pref_orientation">Орієнтація екрана</string>
<string name="pref_orientation_option_auto">Автоматична</string>
<string name="pref_orientation_option_portrait">Портретна</string>
<string name="pref_orientation_option_landscape">Альбомна</string>
</resources>

View file

@ -87,7 +87,7 @@
<string name="pref_long_press">长按</string>
<string name="pref_swipe1">单指轻扫</string>
<string name="pref_swipe2">双指轻扫</string>
<string name="pref_drag">拖动(长按和轻扫)</string>
<string name="pref_drag">拖动</string>
<string name="pref_mouse">鼠标</string>
<string name="pref_mouse_passthrough">鼠标直通</string>
<string name="pref_mouse_passthrough_summary_on">将鼠标事件直接发送到服务器</string>
@ -164,10 +164,16 @@
<string name="pref_discovery_autorun_summary">在主页上时发现服务器</string>
<string name="pref_experimental_toolbar_swipe_close">轻扫以关闭工具栏抽屉</string>
<string name="title_default_security">默认安全度</string>
<string name="msg_hide_remote_pointer_option_moved">“隐藏远程鼠标”已可从
\n“设置→输入→鼠标”开启</string>
<string name="pref_swipe_sensitivity">调节灵敏度</string>
<string name="pref_km_language_switch_to_super">语言切换 → Super 键</string>
<string name="pref_km_back_to_escape">退格键 → Esc 键</string>
<string name="pref_km_right_alt_to_super">右 Alt 键 → Super (开始菜单)键</string>
<string name="msg_drag_gesture_help">为拖动手势分配一个动作将改变长按检测:
\n
\n<b>按住释放</b> → 长按
\n<b>按住滑动</b> → 拖动</string>
<string name="pref_orientation">屏幕方向</string>
<string name="pref_orientation_option_auto">自动</string>
<string name="pref_orientation_option_portrait">竖屏</string>
<string name="pref_orientation_option_landscape">横屏</string>
</resources>

View file

@ -69,7 +69,6 @@
<string name="msg_invalid_vnc_uri">Invalid VNC URI</string>
<string name="msg_copied_to_clipboard">Copied</string>
<string name="msg_key_compat_mode_help">Some servers have limited Unicode support. Legacy key events can help input non-English text.</string>
<string name="msg_hide_remote_pointer_option_moved">\'Hide remote pointer\' is now available in \n\'Settings → Input → Mouse\'</string>
<string name="msg_drag_gesture_help">Assigning an action to Drag gesture will change Long press detection:\n\n<b>Press-hold-release</b> → Long press\n<b>Press-hold-swipe</b> → Drag</string>
<string name="tip_empty_server_list">Server list is empty.\nClick \'<b>+</b>\' to add a server, or\nuse the top address bar to connect directly.</string>
<string name="tip_urlbar">You can enter IP address, hostname, or \'vnc://\' URI.</string>

View file

@ -16,7 +16,7 @@
app:title="@string/pref_experimental_toolbar_swipe_close" />
<SwitchPreference
app:defaultValue="false"
app:defaultValue="true"
app:key="viewer_immersive_mode"
app:summary="@string/pref_experimental_immersive_mode_summary"
app:title="@string/pref_experimental_immersive_mode" />

View file

@ -106,7 +106,7 @@
app:title="@string/title_hide_remote_cursor" />
<ListPreference
app:defaultValue="right"
app:defaultValue="right-click"
app:entries="@array/mouse_back_action_entries"
app:entryValues="@array/mouse_back_action_values"
app:key="mouse_back"

2
extern/wolfssl vendored

@ -1 +1 @@
Subproject commit e722c15be860794179082a05d09e6a90dc77ccf0
Subproject commit 57aac1c50b45275c7a99eca32ad985998b292dc8

View file

@ -0,0 +1,3 @@
* Fixed black screen issue on some Tegra GPUs
* Excluded viewer's toolbar area from system back gesture
* New language: Russian

View file

@ -0,0 +1,3 @@
* Small improvement in connection startup speed
* Fixed a crash on first ever connection when toolbar was aligned to end
* Fixed a crash when entering picture-in-picture for servers with large aspect ratio