From af8ed7af2fb5d79324da571444361c9bbd44993b Mon Sep 17 00:00:00 2001 From: Ukiyograin Date: Thu, 23 Jul 2026 20:04:51 +0800 Subject: [PATCH 1/2] Add drag reorder for game instances --- .../hmcl/game/HMCLGameRepository.java | 15 +++- .../hmcl/setting/LauncherSettings.java | 31 ++++++++ .../org/jackhuang/hmcl/ui/main/RootPage.java | 9 +-- .../hmcl/ui/versions/GameListCell.java | 75 ++++++++++++++++++- .../hmcl/ui/versions/GameListPage.java | 26 ++++++- 5 files changed, 144 insertions(+), 12 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index 11ae454b96a..2a60aee2811 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -202,10 +202,21 @@ private String getSelectedRunningDirectory( } public Stream getDisplayVersions() { + Map customOrder = new HashMap<>(); + List orderedIds = settings().getInstanceSortOrder(gameDirectory.getId()); + for (int i = 0; i < orderedIds.size(); i++) { + customOrder.putIfAbsent(orderedIds.get(i), i); + } + return getVersions().stream() .filter(v -> !v.isHidden()) - .sorted(Comparator.comparing((Version v) -> Lang.requireNonNullElse(v.getReleaseTime(), Instant.EPOCH)) - .thenComparing(v -> VersionNumber.asVersion(v.getId()))); + .sorted(Comparator.comparing((Version v) -> customOrder.getOrDefault(v.getId(), Integer.MAX_VALUE)) + .thenComparing(v -> Lang.requireNonNullElse(v.getReleaseTime(), Instant.EPOCH)) + .thenComparing(v -> VersionNumber.asVersion(getGameVersion(v).orElse(v.getId())))); + } + + public void setInstanceSortOrder(List instanceIds) { + settings().setInstanceSortOrder(gameDirectory.getId(), instanceIds); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java index a92fdf5fce5..c8d3bbdd0a6 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java @@ -72,6 +72,9 @@ public final class LauncherSettings extends ObservableSetting implements JsonSch /// The JSON property name for selected instance IDs keyed by game directory ID. static final String PROPERTY_SELECTED_INSTANCE = "selectedInstance"; + /// The JSON property name for custom instance sort order keyed by game directory ID. + static final String PROPERTY_INSTANCE_SORT_ORDER = "instanceSortOrder"; + /// Default launcher theme used when no stored theme reference is available. public static final ThemeReference DEFAULT_THEME_REFERENCE = new ThemeReference("hmcl.default", null); @@ -654,6 +657,34 @@ public void setSelectedInstance(@Nullable GameDirectoryID gameDirectoryId, @Null } } + /// Custom instance sort order keyed by game directory ID. + @SerializedName(PROPERTY_INSTANCE_SORT_ORDER) + private final ObservableMap> instanceSortOrder = FXCollections.observableHashMap(); + + /// Returns custom instance sort order keyed by game directory ID. + public ObservableMap> getInstanceSortOrder() { + return instanceSortOrder; + } + + /// Returns the custom instance sort order for the given game directory ID. + public List getInstanceSortOrder(@Nullable GameDirectoryID gameDirectoryId) { + ObservableList order = gameDirectoryId != null ? instanceSortOrder.get(gameDirectoryId) : null; + return order == null ? List.of() : List.copyOf(order); + } + + /// Sets the custom instance sort order for the given game directory ID. + public void setInstanceSortOrder(@Nullable GameDirectoryID gameDirectoryId, Collection order) { + if (gameDirectoryId == null) { + return; + } + + if (order.isEmpty()) { + this.instanceSortOrder.remove(gameDirectoryId); + } else { + this.instanceSortOrder.put(gameDirectoryId, FXCollections.observableArrayList(order)); + } + } + // Accounts /// The preferred login type to use when the user wants to add an account. diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java index 01c41530244..d55284fadee 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java @@ -56,12 +56,9 @@ import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.platform.*; -import org.jackhuang.hmcl.util.versioning.VersionNumber; import java.nio.file.Files; import java.nio.file.Path; -import java.time.Instant; -import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; @@ -124,11 +121,7 @@ public MainPage getMainPage() { GameDirectoryManager.registerVersionsListener(repository -> { GameDirectory gameDirectory = repository.getGameDirectory(); - List children = repository.getVersions().parallelStream() - .filter(version -> !version.isHidden()) - .sorted(Comparator - .comparing((Version version) -> Lang.requireNonNullElse(version.getReleaseTime(), Instant.EPOCH)) - .thenComparing(version -> VersionNumber.asVersion(repository.getGameVersion(version).orElse(version.getId())))) + List children = repository.getDisplayVersions() .collect(Collectors.toList()); runInFX(() -> { if (gameDirectory == GameDirectoryManager.getSelectedGameDirectory()) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListCell.java index bb521e39e37..ada1efaa643 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListCell.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListCell.java @@ -25,7 +25,11 @@ import javafx.geometry.Pos; import javafx.scene.Cursor; import javafx.scene.control.ListCell; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.DataFormat; +import javafx.scene.input.Dragboard; import javafx.scene.input.MouseButton; +import javafx.scene.input.TransferMode; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Region; @@ -34,10 +38,18 @@ import org.jackhuang.hmcl.ui.construct.*; import org.jackhuang.hmcl.util.StringUtils; +import java.util.Objects; + import static org.jackhuang.hmcl.ui.FXUtils.determineOptimalPopupPosition; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class GameListCell extends ListCell { + private static final DataFormat GAME_LIST_ITEM = new DataFormat("application/x-hmcl-game-list-item"); + + private static GameListItem draggingItem; + + private final DropHandler dropHandler; + private boolean dragging; private final Region graphic; @@ -53,7 +65,9 @@ public final class GameListCell extends ListCell { private final StringProperty tag = new SimpleStringProperty(); - public GameListCell() { + public GameListCell(DropHandler dropHandler) { + this.dropHandler = dropHandler; + BorderPane root = new BorderPane(); root.getStyleClass().add("md-list-cell"); root.setPadding(new Insets(8, 8, 8, 0)); @@ -143,6 +157,12 @@ public void fire() { root.setCursor(Cursor.HAND); container.setOnMouseClicked(e -> { + if (dragging) { + dragging = false; + e.consume(); + return; + } + GameListItem item = getItem(); if (item == null) return; @@ -157,6 +177,59 @@ public void fire() { popup.show(root, vPosition, JFXPopup.PopupHPosition.LEFT, e.getX(), vPosition == JFXPopup.PopupVPosition.TOP ? e.getY() : e.getY() - root.getHeight()); } }); + + container.setOnDragDetected(e -> { + GameListItem item = getItem(); + if (item == null || e.getButton() != MouseButton.PRIMARY) { + return; + } + + dragging = true; + draggingItem = item; + + Dragboard dragboard = container.startDragAndDrop(TransferMode.MOVE); + ClipboardContent content = new ClipboardContent(); + content.put(GAME_LIST_ITEM, item.getId()); + dragboard.setContent(content); + e.consume(); + }); + + container.setOnDragOver(e -> { + if (canAcceptDrop(e.getDragboard(), getItem())) { + e.acceptTransferModes(TransferMode.MOVE); + e.consume(); + } + }); + + container.setOnDragDropped(e -> { + boolean success = false; + GameListItem targetItem = getItem(); + if (canAcceptDrop(e.getDragboard(), targetItem)) { + dropHandler.onDrop(draggingItem, targetItem, e.getY() > container.getHeight() / 2); + success = true; + } + e.setDropCompleted(success); + e.consume(); + }); + + container.setOnDragDone(e -> { + draggingItem = null; + e.consume(); + }); + } + + private static boolean canAcceptDrop(Dragboard dragboard, GameListItem targetItem) { + return draggingItem != null + && targetItem != null + && draggingItem != targetItem + && dragboard.hasContent(GAME_LIST_ITEM) + && Objects.equals(dragboard.getContent(GAME_LIST_ITEM), draggingItem.getId()) + && draggingItem.getRepository() == targetItem.getRepository(); + } + + @FunctionalInterface + public interface DropHandler { + void onDrop(GameListItem draggedItem, GameListItem targetItem, boolean afterTarget); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java index b83aac3ac5e..e76d62b5c99 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java @@ -185,6 +185,30 @@ public void refreshList() { GameDirectoryManager.getSelectedRepository().refreshVersionsAsync().start(); } + private void moveItem(GameListItem draggedItem, GameListItem targetItem, boolean afterTarget) { + if (draggedItem == null || targetItem == null || draggedItem == targetItem) { + return; + } + + int draggedIndex = sourceList.indexOf(draggedItem); + int targetIndex = sourceList.indexOf(targetItem); + if (draggedIndex < 0 || targetIndex < 0 || draggedIndex == targetIndex) { + return; + } + + sourceList.remove(draggedIndex); + if (draggedIndex < targetIndex) { + targetIndex--; + } + if (afterTarget) { + targetIndex++; + } + sourceList.add(targetIndex, draggedItem); + draggedItem.getRepository().setInstanceSortOrder(sourceList.stream() + .map(GameListItem::getId) + .toList()); + } + @Override protected Skin createDefaultSkin() { return new GameListSkin(this); @@ -250,7 +274,7 @@ public GameListSkin(GameList skinnable) { center.loadingProperty().bind(skinnable.loadingProperty()); center.failedReasonProperty().bind(skinnable.failedReasonProperty()); - listView.setCellFactory(x -> new GameListCell()); + listView.setCellFactory(x -> new GameListCell(skinnable::moveItem)); listView.setItems(skinnable.getItems()); ignoreEvent(listView, KeyEvent.KEY_PRESSED, e -> e.getCode() == KeyCode.ESCAPE); From 76c6f1f815ba29ed61b443c8c2e2939a68c8897f Mon Sep 17 00:00:00 2001 From: Ukiyograin Date: Fri, 24 Jul 2026 12:06:12 +0800 Subject: [PATCH 2/2] Add drag reorder for accounts --- .../org/jackhuang/hmcl/setting/Accounts.java | 29 +++++++- .../hmcl/setting/LauncherSettings.java | 17 +++++ .../hmcl/ui/account/AccountListItem.java | 13 +++- .../hmcl/ui/account/AccountListItemSkin.java | 73 ++++++++++++++++++- .../hmcl/ui/account/AccountListPage.java | 28 ++++++- .../hmcl/ui/decorator/Decorator.java | 2 + HMCL/src/main/resources/assets/css/root.css | 4 - 7 files changed, 158 insertions(+), 8 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java index 713c5d698a2..92f76becb9d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java @@ -182,6 +182,22 @@ private static void addAccountIDs(List accountIDs, List m } } + private static void sortAccountsByCustomOrder() { + Map customOrder = new HashMap<>(); + List orderedAccountIDs = settings().getAccountSortOrder(); + for (int i = 0; i < orderedAccountIDs.size(); i++) { + customOrder.putIfAbsent(orderedAccountIDs.get(i), i); + } + + accounts.sort(Comparator.comparing(account -> customOrder.getOrDefault(account.getAccountID(), Integer.MAX_VALUE))); + } + + private static void updateAccountSortOrder() { + settings().setAccountSortOrder(accounts.stream() + .map(Account::getAccountID) + .toList()); + } + private static void updateAccountMetadataRecords() { // don't update the underlying account records before data loading is completed // otherwise it might cause data loss @@ -334,6 +350,8 @@ public static void init() { } } + sortAccountsByCustomOrder(); + AccountID selectedAccountID = settings().selectedAccountProperty().get(); if (selected == null && selectedAccountID != null) { for (Account account : accounts) { @@ -408,7 +426,10 @@ public void onChanged(Change change) { settings().selectedAccountProperty().set(null); })); accounts.addListener(listener); - accounts.addListener(onInvalidating(Accounts::updateAccountMetadataRecords)); + accounts.addListener(onInvalidating(() -> { + Accounts.updateAccountMetadataRecords(); + Accounts.updateAccountSortOrder(); + })); initialized = true; @@ -442,6 +463,12 @@ public static ObservableList getAccounts() { return accounts; } + public static void setAccountSortOrder(Collection order) { + settings().setAccountSortOrder(order.stream() + .map(Account::getAccountID) + .toList()); + } + public static Account getSelectedAccount() { return selectedAccount.get(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java index c8d3bbdd0a6..5ede5809562 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java @@ -75,6 +75,9 @@ public final class LauncherSettings extends ObservableSetting implements JsonSch /// The JSON property name for custom instance sort order keyed by game directory ID. static final String PROPERTY_INSTANCE_SORT_ORDER = "instanceSortOrder"; + /// The JSON property name for custom account sort order. + static final String PROPERTY_ACCOUNT_SORT_ORDER = "accountSortOrder"; + /// Default launcher theme used when no stored theme reference is available. public static final ThemeReference DEFAULT_THEME_REFERENCE = new ThemeReference("hmcl.default", null); @@ -685,6 +688,20 @@ public void setInstanceSortOrder(@Nullable GameDirectoryID gameDirectoryId, Coll } } + /// Custom account sort order. + @SerializedName(PROPERTY_ACCOUNT_SORT_ORDER) + private final ObservableList accountSortOrder = FXCollections.observableArrayList(); + + /// Returns custom account sort order. + public List getAccountSortOrder() { + return List.copyOf(accountSortOrder); + } + + /// Sets custom account sort order. + public void setAccountSortOrder(Collection order) { + this.accountSortOrder.setAll(order); + } + // Accounts /// The preferred login type to use when the user wants to add an account. diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java index 9fbf4fbd5e9..79012079d57 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java @@ -62,11 +62,13 @@ public class AccountListItem extends RadioButton { private final Account account; + private final DropHandler dropHandler; private final StringProperty title = new SimpleStringProperty(); private final StringProperty subtitle = new SimpleStringProperty(); - public AccountListItem(Account account) { + public AccountListItem(Account account, DropHandler dropHandler) { this.account = account; + this.dropHandler = dropHandler; getStyleClass().clear(); setUserData(account); @@ -198,6 +200,15 @@ public Account getAccount() { return account; } + public DropHandler getDropHandler() { + return dropHandler; + } + + @FunctionalInterface + public interface DropHandler { + void onDrop(AccountListItem draggedItem, AccountListItem targetItem, boolean afterTarget); + } + public String getTitle() { return title.get(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java index 81dd8f94012..26b4b0439c1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java @@ -28,6 +28,11 @@ import javafx.scene.control.Label; import javafx.scene.control.SkinBase; import javafx.scene.control.Tooltip; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.DataFormat; +import javafx.scene.input.Dragboard; +import javafx.scene.input.MouseButton; +import javafx.scene.input.TransferMode; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; @@ -45,16 +50,37 @@ import org.jackhuang.hmcl.ui.construct.SpinnerPane; import org.jackhuang.hmcl.util.javafx.BindingMapping; +import java.util.Objects; + import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class AccountListItemSkin extends SkinBase { + private static final DataFormat ACCOUNT_LIST_ITEM = new DataFormat("application/x-hmcl-account-list-item"); + + private static AccountListItem draggingItem; + + private boolean dragging; public AccountListItemSkin(AccountListItem skinnable) { super(skinnable); BorderPane root = new BorderPane(); root.setCursor(Cursor.HAND); - FXUtils.onClicked(root, skinnable::fire); + if (Controllers.getDecorator() != null) { + Controllers.getDecorator().getDecorator().forbidDraggingWindow(root); + } + root.setOnMouseClicked(e -> { + if (dragging) { + dragging = false; + e.consume(); + return; + } + + if (e.getButton() == MouseButton.PRIMARY) { + skinnable.fire(); + e.consume(); + } + }); JFXRadioButton chkSelected = new JFXRadioButton(); chkSelected.setMouseTransparent(true); @@ -175,9 +201,54 @@ public AccountListItemSkin(AccountListItem skinnable) { root.setStyle("-fx-padding: 8 8 8 0;"); JFXDepthManager.setDepth(root, 1); + root.setOnDragDetected(e -> { + if (e.getButton() != MouseButton.PRIMARY) { + return; + } + + dragging = true; + draggingItem = skinnable; + + Dragboard dragboard = root.startDragAndDrop(TransferMode.MOVE); + ClipboardContent content = new ClipboardContent(); + content.put(ACCOUNT_LIST_ITEM, skinnable.getAccount().getAccountID().toString()); + dragboard.setContent(content); + e.consume(); + }); + + root.setOnDragOver(e -> { + if (canAcceptDrop(e.getDragboard(), skinnable)) { + e.acceptTransferModes(TransferMode.MOVE); + e.consume(); + } + }); + + root.setOnDragDropped(e -> { + boolean success = false; + if (canAcceptDrop(e.getDragboard(), skinnable)) { + skinnable.getDropHandler().onDrop(draggingItem, skinnable, e.getY() > root.getHeight() / 2); + success = true; + } + e.setDropCompleted(success); + e.consume(); + }); + + root.setOnDragDone(e -> { + draggingItem = null; + e.consume(); + }); + getChildren().setAll(root); } + private static boolean canAcceptDrop(Dragboard dragboard, AccountListItem targetItem) { + return draggingItem != null + && targetItem != null + && draggingItem != targetItem + && dragboard.hasContent(ACCOUNT_LIST_ITEM) + && Objects.equals(dragboard.getContent(ACCOUNT_LIST_ITEM), draggingItem.getAccount().getAccountID().toString()); + } + /// Moves the account between local and user account files. private static void moveAccount(AccountListItem skinnable) { Account account = skinnable.getAccount(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java index cd77b84d9cd..9e6e6d03cfe 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java @@ -51,6 +51,7 @@ import org.jackhuang.hmcl.util.javafx.BindingMapping; import org.jackhuang.hmcl.util.javafx.MappedObservableList; +import java.util.ArrayList; import java.util.Locale; import static org.jackhuang.hmcl.setting.SettingsManager.userSettings; @@ -87,10 +88,35 @@ public void changed(ObservableValue o, Boolean oldValue, Bool private final ObjectProperty selectedAccount; public AccountListPage() { - items = MappedObservableList.create(accounts, AccountListItem::new); + items = MappedObservableList.create(accounts, account -> new AccountListItem(account, this::moveItem)); selectedAccount = createSelectedItemPropertyFor(items, Account.class); } + private void moveItem(AccountListItem draggedItem, AccountListItem targetItem, boolean afterTarget) { + if (draggedItem == null || targetItem == null || draggedItem == targetItem) { + return; + } + + ObservableList accountList = Accounts.getAccounts(); + ArrayList reorderedAccounts = new ArrayList<>(accountList); + int draggedIndex = reorderedAccounts.indexOf(draggedItem.getAccount()); + int targetIndex = reorderedAccounts.indexOf(targetItem.getAccount()); + if (draggedIndex < 0 || targetIndex < 0 || draggedIndex == targetIndex) { + return; + } + + Account draggedAccount = reorderedAccounts.remove(draggedIndex); + if (draggedIndex < targetIndex) { + targetIndex--; + } + if (afterTarget) { + targetIndex++; + } + reorderedAccounts.add(targetIndex, draggedAccount); + accountList.setAll(reorderedAccounts); + Accounts.setAccountSortOrder(reorderedAccounts); + } + public ObjectProperty selectedAccountProperty() { return selectedAccount; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java index a9298dfd778..a65ad5b0023 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java @@ -299,6 +299,8 @@ public void capableDraggingWindow(Node node) { } public void forbidDraggingWindow(Node node) { + node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> allowMove.set(false)); + node.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> allowMove.set(false)); node.addEventHandler(MouseEvent.MOUSE_MOVED, e -> { allowMove.set(false); e.consume(); diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index 6b2634f711b..964dd649940 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -1101,10 +1101,6 @@ -fx-border-width: 0 0 1 0; } -.md-list-cell:selected { - -fx-background-color: -monet-secondary-container; -} - .mod-info-list-cell:warning { -fx-background-color: -monet-error-container; }