mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-06 23:09:35 +01:00
Various fixes for handling the Back key in Android and fixes OnClick in all backends
git-svn-id: trunk@34223 -
This commit is contained in:
parent
0e7a6b3226
commit
f2254e0143
@ -46,18 +46,28 @@ public class LCLActivity extends Activity
|
|||||||
//Log.v("lclproject", "LCLSurface.onKeyDown");
|
//Log.v("lclproject", "LCLSurface.onKeyDown");
|
||||||
super.onKeyDown(keyCode, event);
|
super.onKeyDown(keyCode, event);
|
||||||
int eventResult = LCLOnKey(KeyEvent.ACTION_DOWN, keyCode, event, (char) 0);
|
int eventResult = LCLOnKey(KeyEvent.ACTION_DOWN, keyCode, event, (char) 0);
|
||||||
if ((eventResult | 1) != 0) postInvalidate();
|
if ((eventResult & 1) != 0) postInvalidate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean onKeyUp (int keyCode, KeyEvent event)
|
@Override public boolean onKeyUp (int keyCode, KeyEvent event)
|
||||||
{
|
{
|
||||||
int eventResult = LCLOnKey(KeyEvent.ACTION_UP, keyCode, event, event.getDisplayLabel());
|
int eventResult = LCLOnKey(KeyEvent.ACTION_UP, keyCode, event, event.getDisplayLabel());
|
||||||
if ((eventResult | 1) != 0) postInvalidate();
|
if ((eventResult & 1) != 0) postInvalidate();
|
||||||
|
|
||||||
// Handling of the Back hardware key
|
// Handling of the Back hardware key
|
||||||
if ((eventResult | 2) != 0) return false;
|
super.onKeyUp(keyCode, event);
|
||||||
else return true;
|
if ((eventResult & 2) != 0)
|
||||||
|
{
|
||||||
|
//Log.v("lclproject", "BackKey going to home");
|
||||||
|
finish();
|
||||||
|
return false; // From the docs it seams that only returning false should do it, but calling finish() is really necessary
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Log.v("lclproject", "BackKey not going to home");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean onTouchEvent (MotionEvent event)
|
@Override public boolean onTouchEvent (MotionEvent event)
|
||||||
|
|||||||
@ -21,6 +21,10 @@ object Form2: TForm2
|
|||||||
Height = 25
|
Height = 25
|
||||||
Top = 50
|
Top = 50
|
||||||
Width = 80
|
Width = 80
|
||||||
|
OnExit = Edit1Exit
|
||||||
|
OnKeyDown = Edit1KeyDown
|
||||||
|
OnKeyUp = Edit1KeyUp
|
||||||
|
OnUTF8KeyPress = Edit1UTF8KeyPress
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
Text = 'Edit1'
|
Text = 'Edit1'
|
||||||
end
|
end
|
||||||
|
|||||||
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||||
ComCtrls, ExtCtrls;
|
ComCtrls, ExtCtrls, LCLType, LCLProc;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -17,6 +17,10 @@ type
|
|||||||
Edit1: TEdit;
|
Edit1: TEdit;
|
||||||
Image1: TImage;
|
Image1: TImage;
|
||||||
procedure Button1Click(Sender: TObject);
|
procedure Button1Click(Sender: TObject);
|
||||||
|
procedure Edit1Exit(Sender: TObject);
|
||||||
|
procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||||
|
procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||||
|
procedure Edit1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
||||||
private
|
private
|
||||||
{ private declarations }
|
{ private declarations }
|
||||||
public
|
public
|
||||||
@ -37,5 +41,26 @@ begin
|
|||||||
Hide;
|
Hide;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TForm2.Edit1Exit(Sender: TObject);
|
||||||
|
begin
|
||||||
|
DebugLn('[Edit1Exit]');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TForm2.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
DebugLn('[Edit1KeyDown] Key=' + DbgsVKCode(Key));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TForm2.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||||
|
begin
|
||||||
|
DebugLn('[Edit1KeyUp] Key=' + DbgsVKCode(Key));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TForm2.Edit1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
||||||
|
begin
|
||||||
|
DebugLn('[Edit1UTF8KeyPress] Char=' + UTF8Key);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,8 @@ var
|
|||||||
lForm, OldFocusedControl: TWinControl;
|
lForm, OldFocusedControl: TWinControl;
|
||||||
begin
|
begin
|
||||||
OldFocusedControl := FocusedControl;
|
OldFocusedControl := FocusedControl;
|
||||||
|
if ALCLControl = nil then Exit;
|
||||||
|
lForm := GetParentForm(ALCLControl);
|
||||||
if (FocusedControl <> ALCLControl) then
|
if (FocusedControl <> ALCLControl) then
|
||||||
begin
|
begin
|
||||||
// First kill focus in the previous control
|
// First kill focus in the previous control
|
||||||
@ -39,6 +41,9 @@ begin
|
|||||||
FocusedIntfControl := AIntfControl;
|
FocusedIntfControl := AIntfControl;
|
||||||
if AIntfControl <> nil then LCLSendSetFocusMsg(AIntfControl);
|
if AIntfControl <> nil then LCLSendSetFocusMsg(AIntfControl);
|
||||||
|
|
||||||
|
// Also mark in the window information the focus change
|
||||||
|
TCDForm(lForm.Handle).FocusedControl := ALCLControl;
|
||||||
|
|
||||||
// Verify if the virtual keyboard needs to be shown/hidden
|
// Verify if the virtual keyboard needs to be shown/hidden
|
||||||
// Only show if there is no hardware keyboard, but hide always in case
|
// Only show if there is no hardware keyboard, but hide always in case
|
||||||
// the user flopped the keyboard in the mean time
|
// the user flopped the keyboard in the mean time
|
||||||
@ -56,7 +61,6 @@ begin
|
|||||||
ShowVirtualKeyboard();
|
ShowVirtualKeyboard();
|
||||||
|
|
||||||
// Invalidate the entire window to reflect the focus change
|
// Invalidate the entire window to reflect the focus change
|
||||||
lForm := Forms.GetParentForm(ALCLControl);
|
|
||||||
LCLIntf.InvalidateRect(lForm.Handle, nil, False);
|
LCLIntf.InvalidateRect(lForm.Handle, nil, False);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -134,7 +134,7 @@ function Java_com_pascal_lclproject_LCLActivity_LCLOnKey(
|
|||||||
AEvent: jobject; AChar: jchar): jint; cdecl;
|
AEvent: jobject; AChar: jchar): jint; cdecl;
|
||||||
var
|
var
|
||||||
lCurForm: TCDNonNativeForm;
|
lCurForm: TCDNonNativeForm;
|
||||||
lTarget: TWinControl;
|
lTarget, lFocusedControl: TWinControl;
|
||||||
lKey: Word;
|
lKey: Word;
|
||||||
AWideText: widestring;
|
AWideText: widestring;
|
||||||
AUTF8Text: string;
|
AUTF8Text: string;
|
||||||
@ -143,7 +143,7 @@ var
|
|||||||
begin
|
begin
|
||||||
{$ifdef VerboseCDEvents}
|
{$ifdef VerboseCDEvents}
|
||||||
__android_log_write(ANDROID_LOG_INFO,'lclapp',PChar(
|
__android_log_write(ANDROID_LOG_INFO,'lclapp',PChar(
|
||||||
Format('LCLOnKey called AKind=%d AKeyCode=%x AChar=%s', [AKind, AKeyCode, UTF8Encode(WideChar(AChar))])));
|
Format('[LCLOnKey] called AKind=%d AKeyCode=%x AChar=%s', [AKind, AKeyCode, UTF8Encode(WideChar(AChar))])));
|
||||||
{$endif}
|
{$endif}
|
||||||
eventResult := 0;
|
eventResult := 0;
|
||||||
|
|
||||||
@ -167,14 +167,29 @@ begin
|
|||||||
// Handle the Back hardware key
|
// Handle the Back hardware key
|
||||||
if AKeyCode = AKEYCODE_BACK then
|
if AKeyCode = AKEYCODE_BACK then
|
||||||
begin
|
begin
|
||||||
// The back hardware key hides the current form and shows the one bellow it
|
|
||||||
lForm := lCurForm;
|
|
||||||
//DebugLn(Format('CallbackKeyUp D lForm=%x', [PtrInt(lForm)]));
|
//DebugLn(Format('CallbackKeyUp D lForm=%x', [PtrInt(lForm)]));
|
||||||
|
// The back hardware key hides the current form and shows the one bellow it
|
||||||
|
// except if the currently focused control is a text editor, in which case
|
||||||
|
// it will take focus out of the text editor
|
||||||
|
lForm := lCurForm;
|
||||||
|
lFocusedControl := lForm.GetFocusedControl();
|
||||||
|
if (lFocusedControl <> nil) and (csRequiresKeyboardInput in lFocusedControl.ControlStyle) then
|
||||||
|
begin
|
||||||
|
//DebugLn('[LCLOnKey] Sending focus to the form');
|
||||||
|
CDWidgetset.CDSetFocusToControl(lForm.LCLForm, nil);
|
||||||
|
end
|
||||||
// If this is the main form, then go back to desktop
|
// If this is the main form, then go back to desktop
|
||||||
if (Application.MainForm <> nil) and (lForm = TCDForm(Application.MainForm.Handle)) then
|
else if (Application.MainForm <> nil) and (lForm = TCDForm(Application.MainForm.Handle)) then
|
||||||
eventResult := eventResult or 2
|
begin
|
||||||
|
//DebugLn('[LCLOnKey] Back key is going to hide the application');
|
||||||
|
eventResult := eventResult or 2;
|
||||||
|
end
|
||||||
// for other forms, hide them
|
// for other forms, hide them
|
||||||
else HideForm(lForm);
|
else
|
||||||
|
begin
|
||||||
|
//DebugLn('[LCLOnKey] Hiding the form');
|
||||||
|
HideForm(lForm);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
//ACTION_MULTIPLE:
|
//ACTION_MULTIPLE:
|
||||||
|
|||||||
@ -37,6 +37,7 @@ procedure CallbackMouseUp(AWindowHandle: TCDForm; x, y: Integer; Button: TMouseB
|
|||||||
var
|
var
|
||||||
lTarget: TWinControl;
|
lTarget: TWinControl;
|
||||||
lEventPos: TPoint;
|
lEventPos: TPoint;
|
||||||
|
lEventEndsInsideTheControl: Boolean;
|
||||||
begin
|
begin
|
||||||
lTarget := AWindowHandle.LastMouseDownControl;
|
lTarget := AWindowHandle.LastMouseDownControl;
|
||||||
AWindowHandle.LastMouseDownControl := nil;
|
AWindowHandle.LastMouseDownControl := nil;
|
||||||
@ -44,14 +45,18 @@ begin
|
|||||||
AWindowHandle.LCLForm, AWindowHandle.Children, x, y);
|
AWindowHandle.LCLForm, AWindowHandle.Children, x, y);
|
||||||
lEventPos := FormPosToControlPos(lTarget, x, y);
|
lEventPos := FormPosToControlPos(lTarget, x, y);
|
||||||
LCLSendMouseUpMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
|
LCLSendMouseUpMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
|
||||||
LCLSendClickedMsg(lTarget);
|
|
||||||
|
// Send a click only if the event ends inside the control
|
||||||
|
lEventEndsInsideTheControl := (lEventPos.X >= 0) and (lEventPos.Y >= 0)
|
||||||
|
and (lEventPos.X <= lTarget.Width) and (lEventPos.Y <= lTarget.Height);
|
||||||
|
if lEventEndsInsideTheControl then LCLSendClickedMsg(lTarget);
|
||||||
|
|
||||||
// If this is a interface control, send the message to the main LCL control too
|
// If this is a interface control, send the message to the main LCL control too
|
||||||
if IsIntfControl(lTarget) then
|
if IsIntfControl(lTarget) then
|
||||||
begin
|
begin
|
||||||
lTarget := lTarget.Parent;
|
lTarget := lTarget.Parent;
|
||||||
LCLSendMouseUpMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
|
LCLSendMouseUpMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
|
||||||
LCLSendClickedMsg(lTarget);
|
if lEventEndsInsideTheControl then LCLSendClickedMsg(lTarget);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user