Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use System preference for light dark theme #10593

Merged
merged 12 commits into from
Nov 9, 2023
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv

- We added a dropdown menu to let users change the reference library during AUX file import. [#10472](https://github.com/JabRef/jabref/issues/10472)
- We added a button to let users reset the cite command to the default value. [#10569](https://github.com/JabRef/jabref/issues/10569)
- We added the option to use System Preference for Light/Dark Theme [#8729](https://github.com/JabRef/jabref/issues/8729).
- We added [scholar.archive.org](https://scholar.archive.org/) as a new fetcher. [#10498](https://github.com/JabRef/jabref/issues/10498)

### Changed
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ dependencies {
}

implementation 'org.controlsfx:controlsfx:11.2.0'
implementation 'com.github.Dansoftowner:jSystemThemeDetector:3.6'

implementation 'org.jsoup:jsoup:1.16.2'
implementation 'com.konghq:unirest-java:3.14.5'
Expand Down
7 changes: 7 additions & 0 deletions external-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ URL: https://github.com/lemire/javaewah
License: Apache-2.0
```

```yaml
Id: com.jthemedetecor.OsThemeDetector
Project: jSystemThemeDetector
URL: https://github.com/Dansoftowner/jSystemThemeDetector
License: Apache-2.0
```

```yaml
Id: com.konghq.unirest
Project: Unirest for Java
Expand Down
1 change: 1 addition & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,5 @@
requires org.antlr.antlr4.runtime;
requires org.libreoffice.uno;
requires de.saxsys.mvvmfx.validation;
requires com.jthemedetector;
}
11 changes: 7 additions & 4 deletions src/main/java/org/jabref/gui/preferences/general/GeneralTab.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@
<GridPane hgap="10.0" vgap="4.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" percentWidth="30.0"/>
<ColumnConstraints hgrow="NEVER"/>
<ColumnConstraints hgrow="SOMETIMES"/>
</columnConstraints>
<Label styleClass="sectionHeader" text="%Appearance"
GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"/>
GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="3"/>
<Label text="%Language"
GridPane.rowIndex="1" GridPane.columnIndex="0"/>
<ComboBox fx:id="language" prefWidth="200.0"
GridPane.rowIndex="1" GridPane.columnIndex="1"/>

<Label text="%Visual theme"
GridPane.rowIndex="2" GridPane.columnIndex="0"/>
<ComboBox fx:id="theme" prefWidth="200.0"
<ComboBox fx:id="theme" prefWidth="200.0" disable="${themeSyncOs.selected}"
GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<HBox alignment="CENTER_LEFT" spacing="4.0"
GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2">
<CheckBox fx:id="themeSyncOs" text="%Use System Preference"
GridPane.rowIndex="2" GridPane.columnIndex="2"/>
<HBox alignment="CENTER_LEFT" spacing="4.0" disable="${themeSyncOs.selected}"
GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="3">
<TextField fx:id="customThemePath" HBox.hgrow="ALWAYS"/>
<Button fx:id="customThemeBrowse" onAction="#importTheme" styleClass="icon-button,narrow" prefHeight="20.0" prefWidth="20.0">
<graphic>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class GeneralTab extends AbstractPreferenceTabView<GeneralTabViewModel> i

@FXML private ComboBox<Language> language;
@FXML private ComboBox<ThemeTypes> theme;
@FXML private CheckBox themeSyncOs;
@FXML private TextField customThemePath;
@FXML private Button customThemeBrowse;
@FXML private CheckBox fontOverride;
Expand Down Expand Up @@ -104,6 +105,7 @@ public void initialize() {
.install(theme);
theme.itemsProperty().bind(viewModel.themesListProperty());
theme.valueProperty().bindBidirectional(viewModel.selectedThemeProperty());
themeSyncOs.selectedProperty().bindBidirectional(viewModel.themeSyncOsProperty());
customThemePath.textProperty().bindBidirectional(viewModel.customPathToThemeProperty());
EasyBind.subscribe(viewModel.selectedThemeProperty(), theme -> {
boolean isCustomTheme = theme == ThemeTypes.CUSTOM;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public class GeneralTabViewModel implements PreferenceTabViewModel {
private final ReadOnlyListProperty<ThemeTypes> themesListProperty =
new ReadOnlyListWrapper<>(FXCollections.observableArrayList(ThemeTypes.values()));
private final ObjectProperty<ThemeTypes> selectedThemeProperty = new SimpleObjectProperty<>();

private final BooleanProperty themeSyncOsProperty = new SimpleBooleanProperty();

private final StringProperty customPathToThemeProperty = new SimpleStringProperty();

private final BooleanProperty fontOverrideProperty = new SimpleBooleanProperty();
Expand Down Expand Up @@ -178,6 +181,7 @@ public void setValues() {
customPathToThemeProperty.setValue(workspacePreferences.getTheme().getName());
}
}
themeSyncOsProperty.setValue(workspacePreferences.shouldThemeSyncOs());

fontOverrideProperty.setValue(workspacePreferences.shouldOverrideDefaultFontSize());
fontSizeProperty.setValue(String.valueOf(workspacePreferences.getMainFontSize()));
Expand Down Expand Up @@ -215,10 +219,13 @@ public void storeSettings() {
workspacePreferences.setMainFontSize(Integer.parseInt(fontSizeProperty.getValue()));

switch (selectedThemeProperty.get()) {
case LIGHT -> workspacePreferences.setTheme(Theme.light());
case DARK -> workspacePreferences.setTheme(Theme.dark());
case LIGHT ->
workspacePreferences.setTheme(Theme.light());
case DARK ->
workspacePreferences.setTheme(Theme.dark());
case CUSTOM -> workspacePreferences.setTheme(Theme.custom(customPathToThemeProperty.getValue()));
}
workspacePreferences.setThemeSyncOs(themeSyncOsProperty.getValue());

workspacePreferences.setOpenLastEdited(openLastStartupProperty.getValue());
workspacePreferences.setShowAdvancedHints(showAdvancedHintsProperty.getValue());
Expand Down Expand Up @@ -322,6 +329,10 @@ public ObjectProperty<ThemeTypes> selectedThemeProperty() {
return this.selectedThemeProperty;
}

public BooleanProperty themeSyncOsProperty() {
return this.themeSyncOsProperty;
}

public StringProperty customPathToThemeProperty() {
return customPathToThemeProperty;
}
Expand Down
31 changes: 21 additions & 10 deletions src/main/java/org/jabref/gui/theme/ThemeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.jabref.model.util.FileUpdateMonitor;
import org.jabref.preferences.WorkspacePreferences;

import com.jthemedetecor.OsThemeDetector;
import com.tobiasdiez.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -49,6 +50,7 @@ public class ThemeManager {

private Scene mainWindowScene;
private final Set<WebEngine> webEngines = Collections.newSetFromMap(new WeakHashMap<>());
private final OsThemeDetector detector = OsThemeDetector.getDetector();

public ThemeManager(WorkspacePreferences workspacePreferences,
FileUpdateMonitor fileUpdateMonitor,
Expand All @@ -66,13 +68,23 @@ public ThemeManager(WorkspacePreferences workspacePreferences,
baseCssLiveUpdate();

EasyBind.subscribe(workspacePreferences.themeProperty(), theme -> updateThemeSettings());
EasyBind.subscribe(workspacePreferences.themeSyncOsProperty(), theme -> updateThemeSettings());
EasyBind.subscribe(workspacePreferences.shouldOverrideDefaultFontSizeProperty(), should -> updateFontSettings());
EasyBind.subscribe(workspacePreferences.mainFontSizeProperty(), size -> updateFontSettings());
detector.registerListener(isDark -> updateThemeSettings());
}

private void updateThemeSettings() {
Theme newTheme = Objects.requireNonNull(workspacePreferences.getTheme());

if (workspacePreferences.themeSyncOsProperty().getValue()) {
if (detector.isDark()) {
newTheme = Theme.dark();
} else {
newTheme = Theme.light();
}
}

if (newTheme.equals(theme)) {
LOGGER.info("Not updating theme because it hasn't changed");
} else {
Expand Down Expand Up @@ -160,16 +172,15 @@ private void updateBaseCss() {
private void updateAdditionalCss() {
getMainWindowScene().ifPresent(scene -> scene.getStylesheets().setAll(List.of(
baseStyleSheet.getSceneStylesheet().toExternalForm(),
workspacePreferences.getTheme()
.getAdditionalStylesheet().map(styleSheet -> {
URL stylesheetUrl = styleSheet.getSceneStylesheet();
if (stylesheetUrl != null) {
return stylesheetUrl.toExternalForm();
} else {
return "";
}
})
.orElse("")
theme.getAdditionalStylesheet().map(styleSheet -> {
URL stylesheetUrl = styleSheet.getSceneStylesheet();
if (stylesheetUrl != null) {
return stylesheetUrl.toExternalForm();
} else {
return "";
}
})
.orElse("")
)));
}

Expand Down
13 changes: 8 additions & 5 deletions src/main/java/org/jabref/preferences/JabRefPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ public class JabRefPreferences implements PreferencesService {
* There are more default parameters in this map which belong to separate preference classes.
*/
public static final String EXTERNAL_FILE_TYPES = "externalFileTypes";
public static final String FX_THEME = "fxTheme";
public static final String THEME = "fxTheme";
public static final String THEME_SYNC_OS = "themeSyncOs";
public static final String LANGUAGE = "language";
public static final String NAMES_LAST_ONLY = "namesLastOnly";
public static final String ABBR_AUTHOR_NAMES = "abbrAuthorNames";
Expand Down Expand Up @@ -786,7 +787,8 @@ private JabRefPreferences() {
"</font>__NEWLINE__");

// set default theme
defaults.put(FX_THEME, Theme.BASE_CSS);
defaults.put(THEME, Theme.BASE_CSS);
defaults.put(THEME_SYNC_OS, Boolean.FALSE);
setLanguageDependentDefaultValues();
}

Expand Down Expand Up @@ -2083,7 +2085,8 @@ public WorkspacePreferences getWorkspacePreferences() {
getBoolean(OVERRIDE_DEFAULT_FONT_SIZE),
getInt(MAIN_FONT_SIZE),
(Integer) defaults.get(MAIN_FONT_SIZE),
new Theme(get(FX_THEME)),
new Theme(get(THEME)),
getBoolean(THEME_SYNC_OS),
getBoolean(OPEN_LAST_EDITED),
getBoolean(SHOW_ADVANCED_HINTS),
getBoolean(WARN_ABOUT_DUPLICATES_IN_INSPECTION),
Expand All @@ -2098,12 +2101,12 @@ public WorkspacePreferences getWorkspacePreferences() {
});
EasyBind.listen(workspacePreferences.shouldOverrideDefaultFontSizeProperty(), (obs, oldValue, newValue) -> putBoolean(OVERRIDE_DEFAULT_FONT_SIZE, newValue));
EasyBind.listen(workspacePreferences.mainFontSizeProperty(), (obs, oldValue, newValue) -> putInt(MAIN_FONT_SIZE, newValue));
EasyBind.listen(workspacePreferences.themeProperty(), (obs, oldValue, newValue) -> put(FX_THEME, newValue.getName()));
EasyBind.listen(workspacePreferences.themeProperty(), (obs, oldValue, newValue) -> put(THEME, newValue.getName()));
EasyBind.listen(workspacePreferences.themeSyncOsProperty(), (obs, oldValue, newValue) -> putBoolean(THEME_SYNC_OS, newValue));
EasyBind.listen(workspacePreferences.openLastEditedProperty(), (obs, oldValue, newValue) -> putBoolean(OPEN_LAST_EDITED, newValue));
EasyBind.listen(workspacePreferences.showAdvancedHintsProperty(), (obs, oldValue, newValue) -> putBoolean(SHOW_ADVANCED_HINTS, newValue));
EasyBind.listen(workspacePreferences.warnAboutDuplicatesInInspectionProperty(), (obs, oldValue, newValue) -> putBoolean(WARN_ABOUT_DUPLICATES_IN_INSPECTION, newValue));
EasyBind.listen(workspacePreferences.confirmDeleteProperty(), (obs, oldValue, newValue) -> putBoolean(CONFIRM_DELETE, newValue));

return workspacePreferences;
}

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/preferences/WorkspacePreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class WorkspacePreferences {
private final IntegerProperty mainFontSize;
private final IntegerProperty defaultFontSize;
private final ObjectProperty<Theme> theme;
private final BooleanProperty themeSyncOs;
private final BooleanProperty shouldOpenLastEdited;
private final BooleanProperty showAdvancedHints;
private final BooleanProperty warnAboutDuplicatesInInspection;
Expand All @@ -26,6 +27,7 @@ public WorkspacePreferences(Language language,
int mainFontSize,
int defaultFontSize,
Theme theme,
boolean themeSyncOs,
boolean shouldOpenLastEdited,
boolean showAdvancedHints,
boolean warnAboutDuplicatesInInspection,
Expand All @@ -35,6 +37,7 @@ public WorkspacePreferences(Language language,
this.mainFontSize = new SimpleIntegerProperty(mainFontSize);
this.defaultFontSize = new SimpleIntegerProperty(defaultFontSize);
this.theme = new SimpleObjectProperty<>(theme);
this.themeSyncOs = new SimpleBooleanProperty(themeSyncOs);
this.shouldOpenLastEdited = new SimpleBooleanProperty(shouldOpenLastEdited);
this.showAdvancedHints = new SimpleBooleanProperty(showAdvancedHints);
this.warnAboutDuplicatesInInspection = new SimpleBooleanProperty(warnAboutDuplicatesInInspection);
Expand Down Expand Up @@ -93,6 +96,18 @@ public ObjectProperty<Theme> themeProperty() {
return theme;
}

public boolean shouldThemeSyncOs() {
return themeSyncOs.get();
}

public BooleanProperty themeSyncOsProperty() {
return themeSyncOs;
}

public void setThemeSyncOs(boolean themeSyncOs) {
this.themeSyncOs.set(themeSyncOs);
}

public boolean shouldOpenLastEdited() {
return shouldOpenLastEdited.get();
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2083,6 +2083,7 @@ Font\ settings=Font settings
Custom...=Custom...
Dark=Dark
Light=Light
Use\ System\ Preference=Use System Preference
Please\ specify\ a\ css\ theme\ file.=Please specify a css theme file.
You\ must\ enter\ an\ integer\ value\ higher\ than\ 8.=You must enter an integer value higher than 8.
Letters\ after\ duplicate\ generated\ keys=Letters after duplicate generated keys
Expand Down
Loading