Commit 79de52d8 authored by David Bienvenu's avatar David Bienvenu Committed by Commit Bot

Load urls in a window on the current desktop, on Windows 10.

When Chrome is launched with a URL on the command line, and
Chrome is already running, it looks for a browser window to load
the URL in. This CL makes it ignore browser windows that are
not on the current desktop, on Windows 10 (or higher).

Bug: 757853
Change-Id: Ib251619cbcef18809b886b96e21034507ea14654
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1538834
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#652693}
parent 22e75939
...@@ -18,6 +18,14 @@ ...@@ -18,6 +18,14 @@
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#if defined(OS_WIN)
#include <shobjidl.h>
#include <wrl/client.h>
#include "base/win/windows_version.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client.h"
...@@ -36,6 +44,40 @@ const int kMatchOriginalProfile = 1 << 0; ...@@ -36,6 +44,40 @@ const int kMatchOriginalProfile = 1 << 0;
const int kMatchCanSupportWindowFeature = 1 << 1; const int kMatchCanSupportWindowFeature = 1 << 1;
const int kMatchTabbed = 1 << 2; const int kMatchTabbed = 1 << 2;
const int kMatchDisplayId = 1 << 3; const int kMatchDisplayId = 1 << 3;
#if defined(OS_WIN)
const int kMatchCurrentWorkspace = 1 << 4;
#endif
#if defined(OS_WIN)
// Returns true if the browser window is on another virtual desktop, false if
// we can't tell, or it's on the current virtual desktop.
// Must not be called while application is dispatching an input synchronous
// call like SendMessage, because IsWindowOnCurrentVirtualDesktop will return
// an error.
bool IsOnOtherVirtualDesktop(Browser* browser) {
if (base::win::GetVersion() < base::win::VERSION_WIN10)
return false;
Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager;
if (!SUCCEEDED(::CoCreateInstance(__uuidof(VirtualDesktopManager), nullptr,
CLSCTX_ALL,
IID_PPV_ARGS(&virtual_desktop_manager)))) {
return false;
}
BrowserWindow* window = browser->window();
// In tests, |window| can be null.
if (!window)
return false;
BOOL on_current_desktop;
aura::Window* native_win = window->GetNativeWindow();
return native_win &&
SUCCEEDED(virtual_desktop_manager->IsWindowOnCurrentVirtualDesktop(
native_win->GetHost()->GetAcceleratedWidget(),
&on_current_desktop)) &&
!on_current_desktop;
}
#endif // OS_WIN
// Returns true if the specified |browser| matches the specified arguments. // Returns true if the specified |browser| matches the specified arguments.
// |match_types| is a bitmask dictating what parameters to match: // |match_types| is a bitmask dictating what parameters to match:
...@@ -93,6 +135,13 @@ bool BrowserMatches(Browser* browser, ...@@ -93,6 +135,13 @@ bool BrowserMatches(Browser* browser,
if ((match_types & kMatchTabbed) && !browser->is_type_tabbed()) if ((match_types & kMatchTabbed) && !browser->is_type_tabbed())
return false; return false;
#if defined(OS_WIN)
if ((match_types & kMatchCurrentWorkspace) &&
IsOnOtherVirtualDesktop(browser)) {
return false;
}
#endif // OS_WIN
if (match_types & kMatchDisplayId) { if (match_types & kMatchDisplayId) {
return display::Screen::GetScreen() return display::Screen::GetScreen()
->GetDisplayNearestWindow(browser->window()->GetNativeWindow()) ->GetDisplayNearestWindow(browser->window()->GetNativeWindow())
...@@ -134,6 +183,9 @@ Browser* FindBrowserWithTabbedOrAnyType( ...@@ -134,6 +183,9 @@ Browser* FindBrowserWithTabbedOrAnyType(
match_types |= kMatchOriginalProfile; match_types |= kMatchOriginalProfile;
if (display_id != display::kInvalidDisplayId) if (display_id != display::kInvalidDisplayId)
match_types |= kMatchDisplayId; match_types |= kMatchDisplayId;
#if defined(OS_WIN)
match_types |= kMatchCurrentWorkspace;
#endif
Browser* browser = Browser* browser =
FindBrowserMatching(browser_list_impl->begin_last_active(), FindBrowserMatching(browser_list_impl->begin_last_active(),
browser_list_impl->end_last_active(), profile, browser_list_impl->end_last_active(), profile,
......
...@@ -911,6 +911,28 @@ bool StartupBrowserCreator::ProcessLoadApps( ...@@ -911,6 +911,28 @@ bool StartupBrowserCreator::ProcessLoadApps(
return true; return true;
} }
// static
void StartupBrowserCreator::ProcessCommandLineAlreadyRunningImpl(
const base::CommandLine& command_line,
const base::FilePath& cur_dir,
const base::FilePath& profile_path) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
Profile* profile = profile_manager->GetProfileByPath(profile_path);
// The profile isn't loaded yet and so needs to be loaded asynchronously.
if (!profile) {
profile_manager->CreateProfileAsync(
profile_path,
base::BindRepeating(&ProcessCommandLineOnProfileCreated, command_line,
cur_dir),
base::string16(), std::string());
return;
}
StartupBrowserCreator startup_browser_creator;
startup_browser_creator.ProcessCmdLineImpl(
command_line, cur_dir, /*process_startup=*/false, profile, Profiles());
}
// static // static
void StartupBrowserCreator::ProcessCommandLineOnProfileCreated( void StartupBrowserCreator::ProcessCommandLineOnProfileCreated(
const base::CommandLine& command_line, const base::CommandLine& command_line,
...@@ -929,20 +951,15 @@ void StartupBrowserCreator::ProcessCommandLineAlreadyRunning( ...@@ -929,20 +951,15 @@ void StartupBrowserCreator::ProcessCommandLineAlreadyRunning(
const base::CommandLine& command_line, const base::CommandLine& command_line,
const base::FilePath& cur_dir, const base::FilePath& cur_dir,
const base::FilePath& profile_path) { const base::FilePath& profile_path) {
ProfileManager* profile_manager = g_browser_process->profile_manager(); // The Windows-specific code in browser_finder.cc that determines if a window
Profile* profile = profile_manager->GetProfileByPath(profile_path); // is on the current virtual desktop uses a COM interface that can't be
// invoked if we're processing a SendMessage call. So, we post a task to
// The profile isn't loaded yet and so needs to be loaded asynchronously. // finish the command line processing.
if (!profile) { base::ThreadTaskRunnerHandle::Get()->PostTask(
profile_manager->CreateProfileAsync( FROM_HERE,
profile_path, base::BindOnce(
base::Bind(&ProcessCommandLineOnProfileCreated, command_line, cur_dir), &StartupBrowserCreator::ProcessCommandLineAlreadyRunningImpl,
base::string16(), std::string()); command_line, cur_dir, profile_path));
return;
}
StartupBrowserCreator startup_browser_creator;
startup_browser_creator.ProcessCmdLineImpl(command_line, cur_dir, false,
profile, Profiles());
} }
// static // static
......
...@@ -181,6 +181,12 @@ class StartupBrowserCreator { ...@@ -181,6 +181,12 @@ class StartupBrowserCreator {
const base::FilePath& cur_dir, const base::FilePath& cur_dir,
Profile* profile); Profile* profile);
// This is run as a task by ProcessCommandLineAlreadyRunning.
static void ProcessCommandLineAlreadyRunningImpl(
const base::CommandLine& command_line,
const base::FilePath& cur_dir,
const base::FilePath& profile_path);
// Callback after a profile has been created. // Callback after a profile has been created.
static void ProcessCommandLineOnProfileCreated( static void ProcessCommandLineOnProfileCreated(
const base::CommandLine& command_line, const base::CommandLine& command_line,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment