fix(ui): fix last display position not work after restart app. #4222

* Added `SaveWindowPosition` method to `Manager` for saving last window coordinates.
* Introduced API endpoint `/setting/position` to handle window position save requests.
* Updated `getShowAppParams` to utilize saved window position if available.
* Implemented logic in `WoxLauncherController` to save window position after showing the window.
This commit is contained in:
qianlifeng 2025-07-13 23:58:12 +08:00
parent 816f28e3d3
commit 59dc4f8bb3
7 changed files with 72 additions and 11 deletions

View File

@ -677,6 +677,12 @@ func (m *Manager) SavePluginSetting(ctx context.Context, pluginId string, plugin
return nil
}
func (m *Manager) SaveWindowPosition(ctx context.Context, x, y int) error {
m.woxSetting.LastWindowX = x
m.woxSetting.LastWindowY = y
return m.SaveWoxSetting(ctx)
}
func (m *Manager) AddQueryHistory(ctx context.Context, query common.PlainQuery) {
if query.IsEmpty() {
return

View File

@ -37,6 +37,10 @@ type WoxSetting struct {
AppWidth int
MaxResultCount int
ThemeId string
// Window position for last location mode
LastWindowX int
LastWindowY int
}
type LastQueryMode = string
@ -141,5 +145,7 @@ func GetDefaultWoxSetting(ctx context.Context) WoxSetting {
},
EnableAutoBackup: true,
EnableAutoUpdate: true,
LastWindowX: -1, // -1 indicates no saved position
LastWindowY: -1,
}
}

View File

@ -48,6 +48,7 @@ var routers = map[string]func(w http.ResponseWriter, r *http.Request){
"/setting/plugin/update": handleSettingPluginUpdate,
"/setting/userdata/location": handleUserDataLocation,
"/setting/userdata/location/update": handleUserDataLocationUpdate,
"/setting/position": handleSaveWindowPosition,
// events
"/on/focus/lost": handleOnFocusLost,
@ -593,6 +594,34 @@ func handleOpen(w http.ResponseWriter, r *http.Request) {
writeSuccessResponse(w, "")
}
func handleSaveWindowPosition(w http.ResponseWriter, r *http.Request) {
ctx := util.NewTraceContext()
type positionData struct {
X int `json:"x"`
Y int `json:"y"`
}
var pos positionData
err := json.NewDecoder(r.Body).Decode(&pos)
if err != nil {
writeErrorResponse(w, err.Error())
return
}
logger.Info(ctx, fmt.Sprintf("Received window position save request: x=%d, y=%d", pos.X, pos.Y))
saveErr := setting.GetSettingManager().SaveWindowPosition(ctx, pos.X, pos.Y)
if saveErr != nil {
logger.Error(ctx, fmt.Sprintf("Failed to save window position: %s", saveErr.Error()))
writeErrorResponse(w, saveErr.Error())
return
}
logger.Info(ctx, fmt.Sprintf("Window position saved successfully: x=%d, y=%d", pos.X, pos.Y))
writeSuccessResponse(w, "")
}
func handleBackupNow(w http.ResponseWriter, r *http.Request) {
backupErr := setting.GetSettingManager().Backup(util.NewTraceContext(), setting.BackupTypeManual)
if backupErr != nil {

View File

@ -186,7 +186,15 @@ func getShowAppParams(ctx context.Context, showContext common.ShowContext) map[s
case setting.PositionTypeActiveScreen:
position = NewActiveScreenPosition(woxSetting.AppWidth)
case setting.PositionTypeLastLocation:
position = NewLastLocationPosition(0, 0) // Initial values, will be updated by UI
// Use saved window position if available, otherwise use mouse screen position as fallback
if woxSetting.LastWindowX != -1 && woxSetting.LastWindowY != -1 {
logger.Info(ctx, fmt.Sprintf("Using saved window position: x=%d, y=%d", woxSetting.LastWindowX, woxSetting.LastWindowY))
position = NewLastLocationPosition(woxSetting.LastWindowX, woxSetting.LastWindowY)
} else {
logger.Info(ctx, "No saved window position, using mouse screen position as fallback")
// No saved position, fallback to mouse screen position
position = NewMouseScreenPosition(woxSetting.AppWidth)
}
default: // Default to mouse screen
position = NewMouseScreenPosition(woxSetting.AppWidth)
}

View File

@ -214,4 +214,8 @@ class WoxApi {
Future<String> getWoxVersion() async {
return await WoxHttpUtil.instance.postData("/version", null);
}
Future<void> saveWindowPosition(int x, int y) async {
await WoxHttpUtil.instance.postData("/setting/position", {"x": x, "y": y});
}
}

View File

@ -232,16 +232,8 @@ class WoxLauncherController extends GetxController {
if (Platform.isLinux) {
await windowManager.show();
}
if (params.position.type == WoxPositionTypeEnum.POSITION_TYPE_MOUSE_SCREEN.code || params.position.type == WoxPositionTypeEnum.POSITION_TYPE_ACTIVE_SCREEN.code) {
// Use the position calculated by backend
await windowManager.setPosition(Offset(params.position.x.toDouble(), params.position.y.toDouble()));
} else if (params.position.type == WoxPositionTypeEnum.POSITION_TYPE_LAST_LOCATION.code) {
// For last location, we don't need to set position as it will remain where it was last positioned
// but if it's the first time to show, we need to set the position to the center of the screen
var position = await windowManager.getPosition();
if (position.dx == 0 && position.dy == 0) {
await windowManager.center(WoxSettingUtil.instance.currentSetting.appWidth.toDouble(), 600);
}
}
await windowManager.show();
await windowManager.focus();
@ -274,6 +266,21 @@ class WoxLauncherController extends GetxController {
await WoxApi.instance.onHide(currentQuery.value);
}
void saveWindowPositionIfNeeded() {
final setting = WoxSettingUtil.instance.currentSetting;
if (setting.showPosition == WoxPositionTypeEnum.POSITION_TYPE_LAST_LOCATION.code) {
// Run in async task with delay to ensure window position is fully updated
Future.delayed(const Duration(milliseconds: 500), () async {
try {
final position = await windowManager.getPosition();
await WoxApi.instance.saveWindowPosition(position.dx.toInt(), position.dy.toInt());
} catch (e) {
Logger.instance.error(const UuidV4().generate(), "Failed to save window position: $e");
}
});
}
}
Future<void> toggleActionPanel(String traceId) async {
if (resultListViewController.items.isEmpty) {
return;

View File

@ -200,6 +200,7 @@ class _WoxAppState extends State<WoxApp> with WindowListener, ProtocolListener {
}
launcherController.focusQueryBox();
launcherController.saveWindowPositionIfNeeded();
},
child: launcherController.isInSettingView.value ? const WoxSettingView() : const WoxLauncherView(),
);