Skip to content

Commit ffb7b32

Browse files
authored
Merge pull request #2983 from Flow-Launcher/fix-screen-position-multiple-monitor-different-dpi
Fix Multiple Display different DPI causing weird staring position
2 parents 3fff92e + 4bf4282 commit ffb7b32

File tree

1 file changed

+85
-68
lines changed

1 file changed

+85
-68
lines changed

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 85 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public MainWindow(Settings settings, MainViewModel mainVM)
5858
_settings = settings;
5959

6060
InitializeComponent();
61+
// Initialize call twice to work around multi-display alignment issue- https://github.com/Flow-Launcher/Flow.Launcher/issues/2910
62+
InitializePosition();
6163
InitializePosition();
6264

6365
InitSoundEffects();
@@ -72,11 +74,7 @@ public MainWindow(Settings settings, MainViewModel mainVM)
7274
};
7375
}
7476

75-
DispatcherTimer timer = new DispatcherTimer
76-
{
77-
Interval = new TimeSpan(0, 0, 0, 0, 500),
78-
IsEnabled = false
79-
};
77+
DispatcherTimer timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 500), IsEnabled = false };
8078

8179
public MainWindow()
8280
{
@@ -87,6 +85,7 @@ public MainWindow()
8785
private const int WM_EXITSIZEMOVE = 0x0232;
8886
private int _initialWidth;
8987
private int _initialHeight;
88+
9089
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
9190
{
9291
if (msg == WM_ENTERSIZEMOVE)
@@ -95,18 +94,22 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
9594
_initialHeight = (int)Height;
9695
handled = true;
9796
}
97+
9898
if (msg == WM_EXITSIZEMOVE)
9999
{
100-
if ( _initialHeight != (int)Height)
100+
if (_initialHeight != (int)Height)
101101
{
102102
OnResizeEnd();
103103
}
104+
104105
if (_initialWidth != (int)Width)
105106
{
106107
FlowMainWindow.SizeToContent = SizeToContent.Height;
107108
}
109+
108110
handled = true;
109111
}
112+
110113
return IntPtr.Zero;
111114
}
112115

@@ -131,6 +134,7 @@ private void OnResizeEnd()
131134
_settings.MaxResultsToShow = Convert.ToInt32(Math.Truncate(itemCount));
132135
}
133136
}
137+
134138
FlowMainWindow.SizeToContent = SizeToContent.Height;
135139
_viewModel.MainWindowWidth = Width;
136140
}
@@ -175,6 +179,7 @@ private async void OnClosing(object sender, CancelEventArgs e)
175179
private void OnInitialized(object sender, EventArgs e)
176180
{
177181
}
182+
178183
private void OnLoaded(object sender, RoutedEventArgs _)
179184
{
180185
// MouseEventHandler
@@ -186,6 +191,8 @@ private void OnLoaded(object sender, RoutedEventArgs _)
186191
InitializeColorScheme();
187192
WindowsInteropHelper.DisableControlBox(this);
188193
InitProgressbarAnimation();
194+
// Initialize call twice to work around multi-display alignment issue- https://github.com/Flow-Launcher/Flow.Launcher/issues/2910
195+
InitializePosition();
189196
InitializePosition();
190197
PreviewReset();
191198
// since the default main window visibility is visible
@@ -206,6 +213,7 @@ private void OnLoaded(object sender, RoutedEventArgs _)
206213
{
207214
SoundPlay();
208215
}
216+
209217
UpdatePosition();
210218
PreviewReset();
211219
Activate();
@@ -217,7 +225,8 @@ private void OnLoaded(object sender, RoutedEventArgs _)
217225
_viewModel.LastQuerySelected = true;
218226
}
219227

220-
if (_viewModel.ProgressBarVisibility == Visibility.Visible && isProgressBarStoryboardPaused)
228+
if (_viewModel.ProgressBarVisibility == Visibility.Visible &&
229+
isProgressBarStoryboardPaused)
221230
{
222231
_progressBarStoryboard.Begin(ProgressBar, true);
223232
isProgressBarStoryboardPaused = false;
@@ -258,9 +267,12 @@ private void OnLoaded(object sender, RoutedEventArgs _)
258267
MoveQueryTextToEnd();
259268
_viewModel.QueryTextCursorMovedToEnd = false;
260269
}
270+
261271
break;
262272
case nameof(MainViewModel.GameModeStatus):
263-
_notifyIcon.Icon = _viewModel.GameModeStatus ? Properties.Resources.gamemode : Properties.Resources.app;
273+
_notifyIcon.Icon = _viewModel.GameModeStatus
274+
? Properties.Resources.gamemode
275+
: Properties.Resources.app;
264276
break;
265277
}
266278
};
@@ -290,50 +302,59 @@ private void OnLoaded(object sender, RoutedEventArgs _)
290302

291303
private void InitializePosition()
292304
{
293-
if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
294-
{
295-
Top = _settings.WindowTop;
296-
Left = _settings.WindowLeft;
297-
}
298-
else
305+
// Initialize call twice to work around multi-display alignment issue- https://github.com/Flow-Launcher/Flow.Launcher/issues/2910
306+
InitializePositionInner();
307+
InitializePositionInner();
308+
return;
309+
310+
void InitializePositionInner()
299311
{
300-
var screen = SelectedScreen();
301-
switch (_settings.SearchWindowAlign)
312+
if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
302313
{
303-
case SearchWindowAligns.Center:
304-
Left = HorizonCenter(screen);
305-
Top = VerticalCenter(screen);
306-
break;
307-
case SearchWindowAligns.CenterTop:
308-
Left = HorizonCenter(screen);
309-
Top = 10;
310-
break;
311-
case SearchWindowAligns.LeftTop:
312-
Left = HorizonLeft(screen);
313-
Top = 10;
314-
break;
315-
case SearchWindowAligns.RightTop:
316-
Left = HorizonRight(screen);
317-
Top = 10;
318-
break;
319-
case SearchWindowAligns.Custom:
320-
Left = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X + _settings.CustomWindowLeft, 0).X;
321-
Top = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y + _settings.CustomWindowTop).Y;
322-
break;
314+
Top = _settings.WindowTop;
315+
Left = _settings.WindowLeft;
316+
}
317+
else
318+
{
319+
var screen = SelectedScreen();
320+
switch (_settings.SearchWindowAlign)
321+
{
322+
case SearchWindowAligns.Center:
323+
Left = HorizonCenter(screen);
324+
Top = VerticalCenter(screen);
325+
break;
326+
case SearchWindowAligns.CenterTop:
327+
Left = HorizonCenter(screen);
328+
Top = 10;
329+
break;
330+
case SearchWindowAligns.LeftTop:
331+
Left = HorizonLeft(screen);
332+
Top = 10;
333+
break;
334+
case SearchWindowAligns.RightTop:
335+
Left = HorizonRight(screen);
336+
Top = 10;
337+
break;
338+
case SearchWindowAligns.Custom:
339+
Left = WindowsInteropHelper.TransformPixelsToDIP(this,
340+
screen.WorkingArea.X + _settings.CustomWindowLeft, 0).X;
341+
Top = WindowsInteropHelper.TransformPixelsToDIP(this, 0,
342+
screen.WorkingArea.Y + _settings.CustomWindowTop).Y;
343+
break;
344+
}
323345
}
324346
}
325-
326347
}
327348

328349
private void UpdateNotifyIconText()
329350
{
330351
var menu = contextMenu;
331-
((MenuItem)menu.Items[0]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" + _settings.Hotkey + ")";
352+
((MenuItem)menu.Items[0]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") +
353+
" (" + _settings.Hotkey + ")";
332354
((MenuItem)menu.Items[1]).Header = InternationalizationManager.Instance.GetTranslation("GameMode");
333355
((MenuItem)menu.Items[2]).Header = InternationalizationManager.Instance.GetTranslation("PositionReset");
334356
((MenuItem)menu.Items[3]).Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings");
335357
((MenuItem)menu.Items[4]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit");
336-
337358
}
338359

339360
private void InitializeNotifyIcon()
@@ -345,50 +366,34 @@ private void InitializeNotifyIcon()
345366
Visible = !_settings.HideNotifyIcon
346367
};
347368

348-
var openIcon = new FontIcon
349-
{
350-
Glyph = "\ue71e"
351-
};
369+
var openIcon = new FontIcon { Glyph = "\ue71e" };
352370
var open = new MenuItem
353371
{
354-
Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" + _settings.Hotkey + ")",
372+
Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" +
373+
_settings.Hotkey + ")",
355374
Icon = openIcon
356375
};
357-
var gamemodeIcon = new FontIcon
358-
{
359-
Glyph = "\ue7fc"
360-
};
376+
var gamemodeIcon = new FontIcon { Glyph = "\ue7fc" };
361377
var gamemode = new MenuItem
362378
{
363-
Header = InternationalizationManager.Instance.GetTranslation("GameMode"),
364-
Icon = gamemodeIcon
365-
};
366-
var positionresetIcon = new FontIcon
367-
{
368-
Glyph = "\ue73f"
379+
Header = InternationalizationManager.Instance.GetTranslation("GameMode"), Icon = gamemodeIcon
369380
};
381+
var positionresetIcon = new FontIcon { Glyph = "\ue73f" };
370382
var positionreset = new MenuItem
371383
{
372384
Header = InternationalizationManager.Instance.GetTranslation("PositionReset"),
373385
Icon = positionresetIcon
374386
};
375-
var settingsIcon = new FontIcon
376-
{
377-
Glyph = "\ue713"
378-
};
387+
var settingsIcon = new FontIcon { Glyph = "\ue713" };
379388
var settings = new MenuItem
380389
{
381390
Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"),
382391
Icon = settingsIcon
383392
};
384-
var exitIcon = new FontIcon
385-
{
386-
Glyph = "\ue7e8"
387-
};
393+
var exitIcon = new FontIcon { Glyph = "\ue7e8" };
388394
var exit = new MenuItem
389395
{
390-
Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"),
391-
Icon = exitIcon
396+
Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"), Icon = exitIcon
392397
};
393398

394399
open.Click += (o, e) => _viewModel.ToggleFlowLauncher();
@@ -421,6 +426,7 @@ private void InitializeNotifyIcon()
421426
{
422427
_ = SetForegroundWindow(hwndSource.Handle);
423428
}
429+
424430
contextMenu.Focus();
425431
break;
426432
}
@@ -454,8 +460,10 @@ private async void PositionReset()
454460

455461
private void InitProgressbarAnimation()
456462
{
457-
var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
458-
var da1 = new DoubleAnimation(ProgressBar.X1, ActualWidth + 0, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
463+
var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 100,
464+
new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
465+
var da1 = new DoubleAnimation(ProgressBar.X1, ActualWidth + 0,
466+
new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
459467
Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)"));
460468
Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)"));
461469
_progressBarStoryboard.Children.Add(da);
@@ -565,6 +573,7 @@ public void WindowAnimator()
565573
{
566574
clocksb.Begin(ClockPanel);
567575
}
576+
568577
iconsb.Begin(SearchIcon);
569578
windowsb.Begin(FlowMainWindow);
570579
}
@@ -641,6 +650,9 @@ private void UpdatePosition()
641650
{
642651
if (_animating)
643652
return;
653+
654+
// Initialize call twice to work around multi-display alignment issue- https://github.com/Flow-Launcher/Flow.Launcher/issues/2910
655+
InitializePosition();
644656
InitializePosition();
645657
}
646658

@@ -671,7 +683,7 @@ public void HideStartup()
671683
public Screen SelectedScreen()
672684
{
673685
Screen screen = null;
674-
switch(_settings.SearchWindowScreen)
686+
switch (_settings.SearchWindowScreen)
675687
{
676688
case SearchWindowScreens.Cursor:
677689
screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
@@ -693,6 +705,7 @@ public Screen SelectedScreen()
693705
screen = Screen.AllScreens[0];
694706
break;
695707
}
708+
696709
return screen ?? Screen.AllScreens[0];
697710
}
698711

@@ -762,13 +775,15 @@ private void OnKeyDown(object sender, KeyEventArgs e)
762775
_viewModel.LoadContextMenuCommand.Execute(null);
763776
e.Handled = true;
764777
}
778+
765779
break;
766780
case Key.Left:
767781
if (!_viewModel.SelectedIsFromQueryResults() && QueryTextBox.CaretIndex == 0)
768782
{
769783
_viewModel.EscCommand.Execute(null);
770784
e.Handled = true;
771785
}
786+
772787
break;
773788
case Key.Back:
774789
if (specialKeyState.CtrlPressed)
@@ -787,12 +802,13 @@ private void OnKeyDown(object sender, KeyEventArgs e)
787802
}
788803
}
789804
}
805+
790806
break;
791807
default:
792808
break;
793-
794809
}
795810
}
811+
796812
private void OnKeyUp(object sender, KeyEventArgs e)
797813
{
798814
if (e.Key == Key.Up || e.Key == Key.Down)
@@ -808,6 +824,7 @@ private void MainPreviewMouseMove(object sender, System.Windows.Input.MouseEvent
808824
e.Handled = true; // Ignore Mouse Hover when press Arrowkeys
809825
}
810826
}
827+
811828
public void PreviewReset()
812829
{
813830
_viewModel.ResetPreview();

0 commit comments

Comments
 (0)