mirror of https://github.com/termux/termux-app
Changed|Deprecated: Deprecate `use-black-ui` termux property and replace it with `night-mode`
This will not break existing `use-black-ui` settings for users and it will automatically be converted to `night-mode` when properties are loaded from disk but a deprecation message will be logged. This `night-mode` key can be used to set the day/night theme variant for activities used by termux app and its plugin. The user can set a string value to `true` to force use dark variant of theme, `false` to force use light variant of theme or `system` to automatically set theme based on current system settings. The default value is still `system`. The app must be restarted for changes to take effect for existing activities, including main terminal `TermuxActivity`. This is required since "theme != night mode". In future custom theme or color support may be provided that will have both dark and night modes for the same theme.
This commit is contained in:
parent
28ecb64992
commit
d96883c4d6
|
@ -49,6 +49,7 @@ import com.termux.app.settings.properties.TermuxAppSharedProperties;
|
|||
import com.termux.shared.termux.interact.TextInputDialogUtils;
|
||||
import com.termux.shared.logger.Logger;
|
||||
import com.termux.shared.termux.TermuxUtils;
|
||||
import com.termux.shared.theme.ThemeUtils;
|
||||
import com.termux.shared.view.ViewUtils;
|
||||
import com.termux.terminal.TerminalSession;
|
||||
import com.termux.terminal.TerminalSessionClient;
|
||||
|
@ -406,7 +407,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||
|
||||
|
||||
private void setActivityTheme() {
|
||||
if (mProperties.isUsingBlackUI()) {
|
||||
if (ThemeUtils.shouldEnableDarkTheme(this, mProperties.getNightMode())) {
|
||||
this.setTheme(R.style.Theme_Termux_Black);
|
||||
} else {
|
||||
this.setTheme(R.style.Theme_Termux);
|
||||
|
@ -414,7 +415,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||
}
|
||||
|
||||
private void setDrawerTheme() {
|
||||
if (mProperties.isUsingBlackUI()) {
|
||||
if (ThemeUtils.shouldEnableDarkTheme(this, mProperties.getNightMode())) {
|
||||
findViewById(R.id.left_drawer).setBackgroundColor(ContextCompat.getColor(this,
|
||||
android.R.color.background_dark));
|
||||
((ImageButton) findViewById(R.id.settings_button)).setColorFilter(Color.WHITE);
|
||||
|
|
|
@ -21,6 +21,7 @@ import androidx.core.content.ContextCompat;
|
|||
import com.termux.R;
|
||||
import com.termux.app.TermuxActivity;
|
||||
import com.termux.shared.termux.shell.TermuxSession;
|
||||
import com.termux.shared.theme.ThemeUtils;
|
||||
import com.termux.terminal.TerminalSession;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -55,9 +56,9 @@ public class TermuxSessionsListViewController extends ArrayAdapter<TermuxSession
|
|||
return sessionRowView;
|
||||
}
|
||||
|
||||
boolean isUsingBlackUI = mActivity.getProperties().isUsingBlackUI();
|
||||
boolean shouldEnableDarkTheme = ThemeUtils.shouldEnableDarkTheme(mActivity, mActivity.getProperties().getNightMode());
|
||||
|
||||
if (isUsingBlackUI) {
|
||||
if (shouldEnableDarkTheme) {
|
||||
sessionTitleView.setBackground(
|
||||
ContextCompat.getDrawable(mActivity, R.drawable.session_background_black_selected)
|
||||
);
|
||||
|
@ -84,7 +85,7 @@ public class TermuxSessionsListViewController extends ArrayAdapter<TermuxSession
|
|||
} else {
|
||||
sessionTitleView.setPaintFlags(sessionTitleView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
||||
}
|
||||
int defaultColor = isUsingBlackUI ? Color.WHITE : Color.BLACK;
|
||||
int defaultColor = shouldEnableDarkTheme ? Color.WHITE : Color.BLACK;
|
||||
int color = sessionRunning || sessionAtRow.getExitStatus() == 0 ? defaultColor : Color.RED;
|
||||
sessionTitleView.setTextColor(color);
|
||||
return sessionRowView;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package com.termux.shared.models.theme;
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
/** The modes used by to decide night mode for themes. */
|
||||
public enum NightMode {
|
||||
|
||||
/** Night theme should be enabled. */
|
||||
TRUE("true", AppCompatDelegate.MODE_NIGHT_YES),
|
||||
|
||||
/** Dark theme should be enabled. */
|
||||
FALSE("false", AppCompatDelegate.MODE_NIGHT_NO),
|
||||
|
||||
/**
|
||||
* Use night or dark theme depending on system night mode.
|
||||
* https://developer.android.com/guide/topics/resources/providing-resources#NightQualifier
|
||||
*/
|
||||
SYSTEM("system", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||
|
||||
private final String name;
|
||||
private final int mode;
|
||||
|
||||
NightMode(final String name, int mode) {
|
||||
this.name = name;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public static Integer modeOf(String name) {
|
||||
if (TRUE.name.equals(name))
|
||||
return TRUE.mode;
|
||||
else if (FALSE.name.equals(name))
|
||||
return FALSE.mode;
|
||||
else if (SYSTEM.name.equals(name)) {
|
||||
return SYSTEM.mode;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.termux.shared.termux.settings.properties;
|
||||
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.termux.shared.models.theme.NightMode;
|
||||
import com.termux.shared.file.FileUtils;
|
||||
import com.termux.shared.file.filesystem.FileType;
|
||||
import com.termux.shared.settings.properties.SharedProperties;
|
||||
|
@ -16,7 +17,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* Version: v0.15.0
|
||||
* Version: v0.16.0
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Changelog
|
||||
|
@ -69,6 +70,9 @@ import java.util.Set;
|
|||
*
|
||||
* - 0.15.0 (2021-09-05)
|
||||
* - Add `KEY_EXTRA_KEYS_TEXT_ALL_CAPS`.
|
||||
*
|
||||
* - 0.16.0 (2021-10-21)
|
||||
* - Add `KEY_NIGHT_MODE`.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -118,6 +122,7 @@ public final class TermuxPropertyConstants {
|
|||
|
||||
|
||||
/** Defines the key for whether to use black UI */
|
||||
@Deprecated
|
||||
public static final String KEY_USE_BLACK_UI = "use-black-ui"; // Default: "use-black-ui"
|
||||
|
||||
|
||||
|
@ -295,6 +300,24 @@ public final class TermuxPropertyConstants {
|
|||
|
||||
|
||||
|
||||
/** Defines the key for {@link NightMode}. */
|
||||
public static final String KEY_NIGHT_MODE = "night-mode"; // Default: "night-mode"
|
||||
|
||||
public static final String IVALUE_NIGHT_MODE_TRUE = NightMode.TRUE.getName();
|
||||
public static final String IVALUE_NIGHT_MODE_FALSE = NightMode.FALSE.getName();
|
||||
public static final String IVALUE_NIGHT_MODE_SYSTEM = NightMode.SYSTEM.getName();
|
||||
public static final String DEFAULT_IVALUE_NIGHT_MODE = IVALUE_NIGHT_MODE_SYSTEM;
|
||||
|
||||
/** Defines the bidirectional map for {@link NightMode} values and their internal values */
|
||||
public static final ImmutableBiMap<String, String> MAP_NIGHT_MODE =
|
||||
new ImmutableBiMap.Builder<String, String>()
|
||||
.put(IVALUE_NIGHT_MODE_TRUE, IVALUE_NIGHT_MODE_TRUE)
|
||||
.put(IVALUE_NIGHT_MODE_FALSE, IVALUE_NIGHT_MODE_FALSE)
|
||||
.put(IVALUE_NIGHT_MODE_SYSTEM, IVALUE_NIGHT_MODE_SYSTEM)
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
/** Defines the key for whether toggle soft keyboard request will show/hide or enable/disable keyboard */
|
||||
public static final String KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR = "soft-keyboard-toggle-behaviour"; // Default: "soft-keyboard-toggle-behaviour"
|
||||
|
||||
|
@ -340,7 +363,6 @@ public final class TermuxPropertyConstants {
|
|||
KEY_EXTRA_KEYS_TEXT_ALL_CAPS,
|
||||
KEY_HIDE_SOFT_KEYBOARD_ON_STARTUP,
|
||||
KEY_TERMINAL_ONCLICK_URL_OPEN,
|
||||
KEY_USE_BLACK_UI,
|
||||
KEY_USE_CTRL_SPACE_WORKAROUND,
|
||||
KEY_USE_FULLSCREEN,
|
||||
KEY_USE_FULLSCREEN_WORKAROUND,
|
||||
|
@ -368,9 +390,10 @@ public final class TermuxPropertyConstants {
|
|||
KEY_DEFAULT_WORKING_DIRECTORY,
|
||||
KEY_EXTRA_KEYS,
|
||||
KEY_EXTRA_KEYS_STYLE,
|
||||
KEY_NIGHT_MODE,
|
||||
KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR,
|
||||
KEY_VOLUME_KEYS_BEHAVIOUR
|
||||
));
|
||||
));
|
||||
|
||||
/** Defines the set for keys loaded by termux that have default boolean behaviour with false as default.
|
||||
* "true" -> true
|
||||
|
|
|
@ -183,17 +183,47 @@ public abstract class TermuxSharedProperties {
|
|||
* The class that implements the {@link SharedPropertiesParser} interface.
|
||||
*/
|
||||
public static class SharedPropertiesParserClient implements SharedPropertiesParser {
|
||||
@NonNull
|
||||
@Override
|
||||
public Properties preProcessPropertiesOnReadFromDisk(@NonNull Context context, @NonNull Properties properties) {
|
||||
return replaceUseBlackUIProperty(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the
|
||||
* {@link SharedPropertiesParser#getInternalPropertyValueFromValue(Context,String,String)}
|
||||
* interface function.
|
||||
*/
|
||||
@Override
|
||||
public Object getInternalPropertyValueFromValue(Context context, String key, String value) {
|
||||
public Object getInternalPropertyValueFromValue(@NonNull Context context, String key, String value) {
|
||||
return getInternalTermuxPropertyValueFromValue(context, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Properties replaceUseBlackUIProperty(@NonNull Properties properties) {
|
||||
String useBlackUIStringValue = properties.getProperty(TermuxPropertyConstants.KEY_USE_BLACK_UI);
|
||||
if (useBlackUIStringValue == null) return properties;
|
||||
|
||||
Logger.logWarn(LOG_TAG, "Removing deprecated property " + TermuxPropertyConstants.KEY_USE_BLACK_UI + "=" + useBlackUIStringValue);
|
||||
properties.remove(TermuxPropertyConstants.KEY_USE_BLACK_UI);
|
||||
|
||||
// If KEY_NIGHT_MODE is not set
|
||||
if (properties.getProperty(TermuxPropertyConstants.KEY_NIGHT_MODE) == null) {
|
||||
Boolean useBlackUI = SharedProperties.getBooleanValueForStringValue(useBlackUIStringValue);
|
||||
if (useBlackUI != null) {
|
||||
String termuxAppTheme = useBlackUI ? TermuxPropertyConstants.IVALUE_NIGHT_MODE_TRUE :
|
||||
TermuxPropertyConstants.IVALUE_NIGHT_MODE_FALSE;
|
||||
Logger.logWarn(LOG_TAG, "Replacing deprecated property " + TermuxPropertyConstants.KEY_USE_BLACK_UI + "=" + useBlackUI + " with " + TermuxPropertyConstants.KEY_NIGHT_MODE + "=" + termuxAppTheme);
|
||||
properties.put(TermuxPropertyConstants.KEY_NIGHT_MODE, termuxAppTheme);
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A static function that should return the internal termux {@link Object} for a key/value pair
|
||||
* read from properties file.
|
||||
|
@ -213,10 +243,6 @@ public abstract class TermuxSharedProperties {
|
|||
- If the value is not null and does exist in MAP_*, then internal value returned by map will be used.
|
||||
*/
|
||||
switch (key) {
|
||||
/* boolean */
|
||||
case TermuxPropertyConstants.KEY_USE_BLACK_UI:
|
||||
return (boolean) getUseBlackUIInternalPropertyValueFromValue(context, value);
|
||||
|
||||
/* int */
|
||||
case TermuxPropertyConstants.KEY_BELL_BEHAVIOUR:
|
||||
return (int) getBellBehaviourInternalPropertyValueFromValue(value);
|
||||
|
@ -251,6 +277,8 @@ public abstract class TermuxSharedProperties {
|
|||
return (String) getExtraKeysInternalPropertyValueFromValue(value);
|
||||
case TermuxPropertyConstants.KEY_EXTRA_KEYS_STYLE:
|
||||
return (String) getExtraKeysStyleInternalPropertyValueFromValue(value);
|
||||
case TermuxPropertyConstants.KEY_NIGHT_MODE:
|
||||
return (String) getNightModeInternalPropertyValueFromValue(value);
|
||||
case TermuxPropertyConstants.KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR:
|
||||
return (String) getSoftKeyboardToggleBehaviourInternalPropertyValueFromValue(value);
|
||||
case TermuxPropertyConstants.KEY_VOLUME_KEYS_BEHAVIOUR:
|
||||
|
@ -279,18 +307,6 @@ public abstract class TermuxSharedProperties {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} or {@code false} if value is the literal string "true" or "false" respectively regardless of case.
|
||||
* Otherwise returns {@code true} if the night mode is currently enabled in the system.
|
||||
*
|
||||
* @param value The {@link String} value to convert.
|
||||
* @return Returns the internal value for value.
|
||||
*/
|
||||
public static boolean getUseBlackUIInternalPropertyValueFromValue(Context context, String value) {
|
||||
int nightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
return SharedProperties.getBooleanValueForStringValue(TermuxPropertyConstants.KEY_USE_BLACK_UI, value, nightMode == Configuration.UI_MODE_NIGHT_YES, true, LOG_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal value after mapping it based on
|
||||
* {@code TermuxPropertyConstants#MAP_BELL_BEHAVIOUR} if the value is not {@code null}
|
||||
|
@ -314,11 +330,11 @@ public abstract class TermuxSharedProperties {
|
|||
*/
|
||||
public static int getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) {
|
||||
return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE,
|
||||
DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE),
|
||||
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE,
|
||||
TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN,
|
||||
TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX,
|
||||
true, true, LOG_TAG);
|
||||
DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE),
|
||||
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE,
|
||||
TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN,
|
||||
TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX,
|
||||
true, true, LOG_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -487,6 +503,18 @@ public abstract class TermuxSharedProperties {
|
|||
return SharedProperties.getDefaultIfNullOrEmpty(value, TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value itself if it is not {@code null}, otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_NIGHT_MODE}.
|
||||
*
|
||||
* @param value {@link String} value to convert.
|
||||
* @return Returns the internal value for value.
|
||||
*/
|
||||
public static String getNightModeInternalPropertyValueFromValue(String value) {
|
||||
return (String) SharedProperties.getDefaultIfNotInMap(TermuxPropertyConstants.KEY_NIGHT_MODE,
|
||||
TermuxPropertyConstants.MAP_NIGHT_MODE, SharedProperties.toLowerCase(value),
|
||||
TermuxPropertyConstants.DEFAULT_IVALUE_NIGHT_MODE, true, LOG_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value itself if it is not {@code null}, otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR}.
|
||||
*
|
||||
|
@ -535,10 +563,6 @@ public abstract class TermuxSharedProperties {
|
|||
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_ONCLICK_URL_OPEN, true);
|
||||
}
|
||||
|
||||
public boolean isUsingBlackUI() {
|
||||
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_USE_BLACK_UI, true);
|
||||
}
|
||||
|
||||
public boolean isUsingCtrlSpaceWorkaround() {
|
||||
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_USE_CTRL_SPACE_WORKAROUND, true);
|
||||
}
|
||||
|
@ -587,6 +611,16 @@ public abstract class TermuxSharedProperties {
|
|||
return (String) getInternalPropertyValue(TermuxPropertyConstants.KEY_DEFAULT_WORKING_DIRECTORY, true);
|
||||
}
|
||||
|
||||
public String getNightMode() {
|
||||
return (String) getInternalPropertyValue(TermuxPropertyConstants.KEY_NIGHT_MODE, true);
|
||||
}
|
||||
|
||||
/** Get the {@link TermuxPropertyConstants#KEY_NIGHT_MODE} value from the properties file on disk. */
|
||||
public static String getNightMode(Context context) {
|
||||
return (String) TermuxSharedProperties.getTermuxInternalPropertyValue(context,
|
||||
TermuxPropertyConstants.KEY_NIGHT_MODE);
|
||||
}
|
||||
|
||||
public boolean shouldEnableDisableSoftKeyboardOnToggle() {
|
||||
return (boolean) TermuxPropertyConstants.IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_ENABLE_DISABLE.equals(getInternalPropertyValue(TermuxPropertyConstants.KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR, true));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.termux.shared.theme;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import com.termux.shared.models.theme.NightMode;
|
||||
|
||||
public class ThemeUtils {
|
||||
|
||||
/**
|
||||
* Will return true if system has enabled night mode.
|
||||
* https://developer.android.com/guide/topics/resources/providing-resources#NightQualifier
|
||||
*/
|
||||
public static boolean isNightModeEnabled(Context context) {
|
||||
if (context == null) return false;
|
||||
return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||
|
||||
}
|
||||
|
||||
/** Will return true if mode is set to {@link NightMode#TRUE}, otherwise will return true if
|
||||
* mode is set to {@link NightMode#SYSTEM} and night mode is enabled by system. */
|
||||
public static boolean shouldEnableDarkTheme(Context context, String name) {
|
||||
if (NightMode.TRUE.getName().equals(name))
|
||||
return true;
|
||||
else if (NightMode.FALSE.getName().equals(name))
|
||||
return false;
|
||||
else if (NightMode.SYSTEM.getName().equals(name)) {
|
||||
return isNightModeEnabled(context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue