Skip to content

Commit

Permalink
Dramatic simplification to keyboard restore
Browse files Browse the repository at this point in the history
  • Loading branch information
harshad1 committed Sep 27, 2023
1 parent 7b1db5b commit 105e847
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 59 deletions.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
android:label="@string/app_name"
android:launchMode="singleTop"
android:taskAffinity=".activity.MainActivity"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize">
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do
private MarkorWebViewClient _webViewClient;
private boolean _nextConvertToPrintMode = false;
private MenuItem _saveMenuItem, _undoMenuItem, _redoMenuItem;
private Boolean defocusImeState = null;

public DocumentEditAndViewFragment() {
super();
Expand Down Expand Up @@ -225,6 +226,18 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
updateUndoRedoIconStates();
});
_hlEditor.addTextChangedListener(GsTextWatcherAdapter.after(s -> debounced.run()));

// Restore keyboard when we regain focus
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
_hlEditor.getViewTreeObserver().addOnWindowFocusChangeListener(hasFocus -> {
if (hasFocus) {
_cu.showIme(getActivity(), defocusImeState, _hlEditor);
defocusImeState = null;
} else {
defocusImeState = GsContextUtils.isImeOpen(_hlEditor);
}
});
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
import android.view.WindowManager;

import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;

import net.gsantner.markor.ApplicationObject;
import net.gsantner.markor.R;
import net.gsantner.markor.model.AppSettings;
import net.gsantner.markor.util.MarkorContextUtils;
import net.gsantner.opoc.frontend.base.GsActivityBase;
import net.gsantner.opoc.util.GsCollectionUtils;

import java.util.List;

public abstract class MarkorBaseActivity extends GsActivityBase<AppSettings, MarkorContextUtils> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ protected final boolean runCommonAction(final @StringRes int action) {
return true;
}
case R.string.abid_common_insert_snippet: {
MarkorDialogFactory.showInsertSnippetDialog(getActivity(), _hlEditor, (snip) -> {
MarkorDialogFactory.showInsertSnippetDialog(getActivity(), (snip) -> {
_hlEditor.insertOrReplaceTextOnCursor(TextViewUtils.interpolateEscapedDateTime(snip));
_lastSnip = snip;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ public boolean onActionLongClick(final @StringRes int action) {

switch (action) {
case R.string.abid_todotxt_add_context: {
MarkorDialogFactory.showSttKeySearchDialog(getActivity(), _hlEditor, R.string.browse_by_context, true, true, GsContextUtils.isImeOpen(_hlEditor), TodoTxtFilter.TYPE.CONTEXT);
MarkorDialogFactory.showSttKeySearchDialog(getActivity(), _hlEditor, R.string.browse_by_context, true, true, TodoTxtFilter.TYPE.CONTEXT);
return true;
}
case R.string.abid_todotxt_add_project: {
MarkorDialogFactory.showSttKeySearchDialog(getActivity(), _hlEditor, R.string.browse_by_project, true, true, GsContextUtils.isImeOpen(_hlEditor), TodoTxtFilter.TYPE.PROJECT);
MarkorDialogFactory.showSttKeySearchDialog(getActivity(), _hlEditor, R.string.browse_by_project, true, true, TodoTxtFilter.TYPE.PROJECT);
return true;
}
case R.string.abid_todotxt_sort_todo: {
Expand Down Expand Up @@ -252,7 +252,7 @@ private void addRemoveItems(final String prefix, final GsCallback.r1<Collection<

final boolean append = _appSettings.isTodoAppendProConOnEndEnabled();

MarkorDialogFactory.showUpdateItemsDialog(getActivity(), R.string.insert_context, all, current, _hlEditor,
MarkorDialogFactory.showUpdateItemsDialog(getActivity(), R.string.insert_context, all, current,
updated -> {
final TextViewUtils.ChunkedEditable chunk = TextViewUtils.ChunkedEditable.wrap(_hlEditor.getText());
for (final String item : GsCollectionUtils.setDiff(current, updated)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,6 @@ public static void showInsertImageOrLinkDialog(
}
};

final Boolean restoreIme = GsContextUtils.isImeOpen(edit);

final AlertDialog dialog =
builder.setView(view)
.setTitle(actionTitle)
Expand Down Expand Up @@ -213,10 +211,7 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {
"" + MarkorContextUtils.REQUEST_CAMERA_PICTURE, "" + MarkorContextUtils.REQUEST_PICK_PICTURE
);

dialog.setOnDismissListener(d -> {
LocalBroadcastManager.getInstance(activity).unregisterReceiver(br);
edit.postDelayed(() -> GsContextUtils.instance.showIme(activity, restoreIme, edit), 250);
});
dialog.setOnDismissListener(d -> LocalBroadcastManager.getInstance(activity).unregisterReceiver(br));

// Get picture from camera
buttonPictureCamera.setOnClickListener(button -> shu.requestCameraPicture(activity, attachmentDir));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;

Expand Down Expand Up @@ -234,27 +233,25 @@ public static void showSttFilteringDialog(final Activity activity, final EditTex
final DialogOptions dopt = new DialogOptions();
baseConf(activity, dopt);

final Boolean showIme = GsContextUtils.isImeOpen(text);

final List<String> options = new ArrayList<>();
final List<Integer> icons = new ArrayList<>();
final List<GsCallback.a0> callbacks = new ArrayList<>();

options.add(activity.getString(R.string.priority));
icons.add(R.drawable.ic_star_black_24dp);
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_priority, false, false, showIme, TodoTxtFilter.TYPE.PRIORITY));
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_priority, false, false, TodoTxtFilter.TYPE.PRIORITY));

options.add(activity.getString(R.string.due_date));
icons.add(R.drawable.ic_date_range_black_24dp);
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_due_date, false, false, showIme, TodoTxtFilter.TYPE.DUE));
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_due_date, false, false, TodoTxtFilter.TYPE.DUE));

options.add(activity.getString(R.string.project));
icons.add(R.drawable.ic_new_label_black_24dp);
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_project, true, true, showIme, TodoTxtFilter.TYPE.PROJECT));
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_project, true, true, TodoTxtFilter.TYPE.PROJECT));

options.add(activity.getString(R.string.context));
icons.add(R.drawable.gs_email_sign_black_24dp);
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_context, true, true, showIme, TodoTxtFilter.TYPE.CONTEXT));
callbacks.add(() -> showSttKeySearchDialog(activity, text, R.string.browse_by_context, true, true, TodoTxtFilter.TYPE.CONTEXT));

options.add(activity.getString(R.string.advanced_filtering));
icons.add(R.drawable.ic_extension_black_24dp);
Expand All @@ -268,7 +265,6 @@ public static void showSttFilteringDialog(final Activity activity, final EditTex
return TodoTxtFilter.isMatchQuery(new TodoTxtTask(line), query);
};
addSaveQuery(activity, dopt2, () -> queryHolder[0]);
addRestoreKeyboard(activity, dopt2, text, showIme);
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
});

Expand Down Expand Up @@ -326,7 +322,6 @@ public static void showSttFilteringDialog(final Activity activity, final EditTex
* @param title Dialog title
* @param enableSearch Whether key search is enabled
* @param enableAnd Whether 'and' keys makes sense / is enabled
* @param showIme Whether to show IME when done (if == true)
* @param queryType Key used with TodoTxtFilter
*/
public static void showSttKeySearchDialog(
Expand All @@ -335,7 +330,6 @@ public static void showSttKeySearchDialog(
final int title,
final boolean enableSearch,
final boolean enableAnd,
final Boolean showIme,
final TodoTxtFilter.TYPE queryType
) {

Expand Down Expand Up @@ -382,7 +376,6 @@ public static void showSttKeySearchDialog(
dopt.isSearchEnabled = enableSearch;
dopt.searchHintText = R.string.search;
dopt.isMultiSelectEnabled = true;
addRestoreKeyboard(activity, dopt, text, showIme);

// Callback to actually show tasks
// -------------------------------------
Expand All @@ -398,7 +391,6 @@ public static void showSttKeySearchDialog(
final DialogOptions doptSel = makeSttLineSelectionDialog(activity, text, t -> TodoTxtFilter.isMatchQuery(t, query));
setQueryTitle(doptSel, activity.getString(title), query);
addSaveQuery(activity, doptSel, () -> query);
addRestoreKeyboard(activity, doptSel, text, showIme);

GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, doptSel);
};
Expand Down Expand Up @@ -482,19 +474,9 @@ public static void showSttSearchDialog(final Activity activity, final EditText t
dialog.dismiss();
SearchAndReplaceTextDialog.showSearchReplaceDialog(activity, text.getText(), TextViewUtils.getSelection(text));
};
addRestoreKeyboard(activity, dopt, text);
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

// Restore the keyboard when dialog closes if keyboard is open when dialog was called
private static void addRestoreKeyboard(final Activity activity, final DialogOptions options, final EditText edit) {
addRestoreKeyboard(activity, options, edit, GsContextUtils.isImeOpen(edit));
}

private static void addRestoreKeyboard(final Activity activity, final DialogOptions options, final EditText edit, final Boolean restore) {
options.dismissCallback = (d) -> edit.postDelayed(() -> GsContextUtils.instance.showIme(activity, restore, edit), 250);
}

/**
* Allow to choose between Hexcolor / foreground / background color, pass back stringid
*/
Expand Down Expand Up @@ -529,7 +511,6 @@ public static void showInsertItemsDialog(
final Activity activity,
final @StringRes int title,
final List<String> data,
final @Nullable EditText text, // Passed in here for keyboard restore
final GsCallback.a1<String> insertCallback
) {
GsSearchOrCustomTextDialog.DialogOptions dopt = new GsSearchOrCustomTextDialog.DialogOptions();
Expand All @@ -544,9 +525,6 @@ public static void showInsertItemsDialog(
insertCallback.callback(dopt.data.get(pi).toString());
}
};
if (text != null) {
addRestoreKeyboard(activity, dopt, text);
}
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

Expand All @@ -556,7 +534,6 @@ public static void showUpdateItemsDialog(
final @StringRes int title,
final Set<String> allKeys,
final Set<String> currentKeys,
final @Nullable EditText text, // Passed in here for keyboard restore
final GsCallback.a1<Collection<String>> callback
) {
GsSearchOrCustomTextDialog.DialogOptions dopt = new GsSearchOrCustomTextDialog.DialogOptions();
Expand All @@ -571,10 +548,6 @@ public static void showUpdateItemsDialog(
dopt.positionCallback = (newSel) -> callback.callback(
GsCollectionUtils.map(newSel, pi -> dopt.data.get(pi).toString()));

if (text != null) {
addRestoreKeyboard(activity, dopt, text);
}

GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

Expand All @@ -599,7 +572,6 @@ public static void showSearchDialog(final Activity activity, final EditText text
};
dopt.neutralButtonText = R.string.search_and_replace;
dopt.positionCallback = (result) -> TextViewUtils.selectLines(text, result);
addRestoreKeyboard(activity, dopt, text);
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

Expand Down Expand Up @@ -676,7 +648,6 @@ public static void showHeadlineDialog(
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
dopt.gravity = Gravity.TOP;
addRestoreKeyboard(activity, dopt, edit);
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

Expand Down Expand Up @@ -812,20 +783,18 @@ public static Map<String, File> getSnippets(final AppSettings as) {
return texts;
}

public static void showInsertSnippetDialog(final Activity activity, @Nullable final EditText edit, final GsCallback.a1<String> callback) {
public static void showInsertSnippetDialog(final Activity activity, final GsCallback.a1<String> callback) {
final DialogOptions dopt = new DialogOptions();
baseConf(activity, dopt);

final Map<String, File> texts = getSnippets(as());
final Boolean showIme = edit != null ? GsContextUtils.isImeOpen(edit) : null;

final List<String> data = new ArrayList<>(texts.keySet());
dopt.data = data;
dopt.isSearchEnabled = true;
dopt.titleText = R.string.insert_snippet;
dopt.messageText = Html.fromHtml("<small><small>" + as().getSnippetsFolder().getAbsolutePath() + "</small></small>");
dopt.positionCallback = (ind) -> callback.callback(GsFileUtils.readTextFileFast(texts.get(data.get(ind.get(0)))).first);
addRestoreKeyboard(activity, dopt, edit, showIme);
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#########################################################*/
package net.gsantner.markor.frontend.textview;

import android.animation.ObjectAnimator;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
Expand All @@ -20,6 +22,7 @@
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowInsets;
import android.widget.EditText;
import android.widget.TextView;

Expand Down Expand Up @@ -722,4 +725,12 @@ public static boolean isViewVisible(final View view) {
final Rect screen = new Rect(0, 0, metrics.widthPixels, metrics.heightPixels);
return isGlobalVisible && Rect.intersects(actualPosition, screen);
}

// Check if keyboard open. Only available after android 11 :(
public static Boolean isImeOpen(final View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return view.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
}
return null; // Uncertain
}
}
14 changes: 2 additions & 12 deletions app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.webkit.MimeTypeMap;
Expand Down Expand Up @@ -2499,17 +2498,8 @@ public void showSnackBar(final Activity context, @StringRes int stringResId, boo
.show();
}


// Check if keyboard open. Only available after android 11 :(
public static Boolean isImeOpen(final View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return view.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
}
return null; // Uncertain
}

public <T extends GsContextUtils> T showIme(final Activity activity, final Boolean show, final View... view) {
if (activity != null && show != null) {
public <T extends GsContextUtils> T showIme(final Activity activity, final boolean show, final View... view) {
if (activity != null) {
final InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
final View focus = (view != null && view.length > 0) ? view[0] : activity.getCurrentFocus();
final IBinder token = focus != null ? focus.getWindowToken() : null;
Expand Down

0 comments on commit 105e847

Please sign in to comment.