启动部分(chrome.exe)
wWinMain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
int MainDllLoader::Launch(HINSTANCE instance, base::TimeTicks exe_entry_point_ticks) { // ... base::FilePath file; dll_ = Load(&file); if (!dll_) return chrome::RESULT_CODE_MISSING_DATA; // ... OnBeforeLaunch(cmd_line, process_type_, file); DLL_MAIN chrome_main = reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); int rc = chrome_main(instance, &sandbox_info, exe_entry_point_ticks.ToInternalValue()); return rc; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class ChromiumDllLoader : public MainDllLoader { protected: void OnBeforeLaunch(const base::CommandLine& cmd_line, const std::string& process_type, const base::FilePath& dll_path) override {} }; MainDllLoader* MakeMainDllLoader() { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) return new ChromeDllLoader(); #else return new ChromiumDllLoader(); #endif } |
1 2 3 4 5 6 7 8 9 10 11 12 |
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { // ... VLOG(1) << "About to load main DLL."; MainDllLoader* loader = MakeMainDllLoader(); int rc = loader->Launch(instance, exe_entry_point_ticks); loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded(); delete loader; // ... return rc; } |
chrome.dll
ChromeMain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance, sandbox::SandboxInterfaceInfo* sandbox_info, int64_t exe_entry_point_ticks) { // ... ChromeMainDelegate chrome_main_delegate( base::TimeTicks::FromInternalValue(exe_entry_point_ticks)); content::ContentMainParams params(&chrome_main_delegate); auto crash_on_detach_resetter = base::ScopedClosureRunner( base::BindOnce(&base::win::SetShouldCrashOnProcessDetach, base::win::ShouldCrashOnProcessDetach())); base::win::SetShouldCrashOnProcessDetach(true); base::win::SetAbortBehaviorForCrashReporting(); // ... int rv = content::ContentMain(std::move(params)); if (chrome::IsNormalResultCode(static_cast<chrome::ResultCode>(rv))) return content::RESULT_CODE_NORMAL_EXIT; return rv; } |
content.dll
1 2 3 4 |
int NO_STACK_PROTECTOR ContentMain(ContentMainParams params) { auto runner = ContentMainRunner::Create(); return RunContentProcess(std::move(params), runner.get()); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int NO_STACK_PROTECTOR RunContentProcess(ContentMainParams params, ContentMainRunner* content_main_runner) { // ... if (IsSubprocess()) CommonSubprocessInit(); exit_code = content_main_runner->Run(); // ... return exit_code; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
int NO_STACK_PROTECTOR ContentMainRunnerImpl::Run() { const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); std::string process_type = command_line->GetSwitchValueASCII(switches::kProcessType); // Run this logic on all child processes. if (!process_type.empty()) { if (process_type != switches::kZygoteProcess) { // Zygotes will run this at a later point in time when the command line // has been updated. CreateChildThreadPool(process_type); if (delegate_->ShouldCreateFeatureList( ContentMainDelegate::InvokedInChildProcess())) { InitializeFieldTrialAndFeatureList(); } if (delegate_->ShouldInitializeMojo( ContentMainDelegate::InvokedInChildProcess())) { InitializeMojoCore(); } delegate_->PostEarlyInitialization( ContentMainDelegate::InvokedInChildProcess()); base::allocator::PartitionAllocSupport::Get() ->ReconfigureAfterFeatureListInit(process_type); } } // ... if (process_type.empty()) return RunBrowser(std::move(main_params), start_minimal_browser); // return ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
int ContentMainRunnerImpl::RunBrowser(MainFunctionParams main_params, bool start_minimal_browser) { // ... return RunBrowserProcessMain(std::move(main_params), delegate_); } int RunBrowserProcessMain(MainFunctionParams main_function_params, ContentMainDelegate* delegate) { // ... auto exit_code = delegate->RunProcess("", std::move(main_function_params)); if (absl::holds_alternative<int>(exit_code)) { DCHECK_GE(absl::get<int>(exit_code), 0); return absl::get<int>(exit_code); } return BrowserMain(std::move(absl::get<MainFunctionParams>(exit_code))); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int BrowserMain(MainFunctionParams parameters) { // ... std::unique_ptr<BrowserMainRunnerImpl> main_runner( BrowserMainRunnerImpl::Create()); int exit_code = main_runner->Initialize(std::move(parameters)); if (exit_code >= 0) return exit_code; exit_code = main_runner->Run(); // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int BrowserMainRunnerImpl::Run() { DCHECK(initialization_started_); DCHECK(!is_shutdown_); main_loop_->RunMainMessageLoop(); return main_loop_->GetResultCode(); } void BrowserMainLoop::RunMainMessageLoop() { // ... if (InterceptMainMessageLoopRun() != ProceedWithMainMessageLoopRun(true)) return; auto main_run_loop = std::make_unique<base::RunLoop>(); if (parts_) parts_->WillRunMainMessageLoop(main_run_loop); DCHECK(main_run_loop); main_run_loop->Run(); } |
base.dll
- 消息泵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void RunLoop::Run(const Location& location) { // ... const bool application_tasks_allowed = delegate_->active_run_loops_.size() == 1U || type_ == Type::kNestableTasksAllowed; delegate_->Run(application_tasks_allowed, TimeDelta::Max()); AfterRun(); } void ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, TimeDelta timeout) { // ... main_thread_only().quit_pending = false; hang_watch_scope_.emplace(); if (application_tasks_allowed && !main_thread_only().task_execution_allowed) { // Allow nested task execution as explicitly requested. DCHECK(RunLoop::IsNestedOnCurrentThread()); main_thread_only().task_execution_allowed = true; pump_->Run(this); main_thread_only().task_execution_allowed = false; } else { pump_->Run(this); } // ... } |
1 2 3 4 5 6 7 8 |
void MessagePumpWin::Run(Delegate* delegate) { RunState run_state(delegate); if (run_state_) run_state.is_nested = true; AutoReset<RunState*> auto_reset_run_state(&run_state_, &run_state); DoRunLoop(); } |
- 消息循环
1 2 3 4 5 6 7 8 9 10 11 12 |
void MessagePumpForUI::DoRunLoop() { for(;;) { in_native_loop_ = false; bool more_work_is_plausible = ProcessNextWindowsMessage(); in_native_loop_ = false; if (run_state_->should_quit) break; // ... } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
bool MessagePumpForUI::ProcessNextWindowsMessage() { MSG msg; bool has_msg = false; bool more_work_is_plausible = false; { auto scoped_do_work_item = run_state_->delegate->BeginWorkItem(); { DWORD queue_status = ::GetQueueStatus(QS_SENDMESSAGE); if (HIWORD(queue_status) & QS_SENDMESSAGE) more_work_is_plausible = true; } { has_msg = ::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) != FALSE; } } if (has_msg) more_work_is_plausible |= ProcessMessageHelper(msg); return more_work_is_plausible; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) { if (msg.message == WM_QUIT) { return true; } if (msg.message == kMsgHaveWork && msg.hwnd == message_window_.hwnd()) return ProcessPumpReplacementMessage(); for (Observer& observer : observers_) observer.WillDispatchMSG(msg); ::TranslateMessage(&msg); ::DispatchMessage(&msg); for (Observer& observer : observers_) observer.DidDispatchMSG(msg); return true; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
bool MessagePumpForUI::ProcessPumpReplacementMessage() { MSG msg; bool have_message = false; { have_message = ::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) != FALSE; } if (!have_message) return false; if (msg.message == WM_QUIT) { ::PostQuitMessage(static_cast<int>(msg.wParam)); return true; } else if (msg.message == WM_TIMER && msg.wParam == reinterpret_cast<UINT_PTR>(this)) { HandleTimerMessage(); return true; } ScheduleWork(); return ProcessMessageHelper(msg); } |
- 将消息分派给窗口过程处理函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) { if (msg.message == WM_QUIT) { return true; } if (msg.message == kMsgHaveWork && msg.hwnd == message_window_.hwnd()) return ProcessPumpReplacementMessage(); auto scoped_do_work_item = run_state_->delegate->BeginWorkItem(); for (Observer& observer : observers_) observer.WillDispatchMSG(msg); ::TranslateMessage(&msg); ::DispatchMessage(&msg); for (Observer& observer : observers_) observer.DidDispatchMSG(msg); return true; } |
user32.dll
1 2 3 |
DispatchMessageWorker(); CallWinProcCheckWow(); |
ui_gfx.dll
1 2 3 4 5 6 7 8 |
WrappedWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { LRESULT rv = 0; __try { rv = proc(hwnd, message, wparam, lparam); } __except (CallExceptionFilter(GetExceptionInformation())) { } return rv; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param) { WindowImpl* window = nullptr; if (message == WM_NCCREATE) { CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param); window = reinterpret_cast<WindowImpl*>(cs->lpCreateParams); DCHECK(window); gfx::SetWindowUserData(hwnd, window); window->hwnd_ = hwnd; window->got_create_ = true; if (hwnd) window->got_valid_hwnd_ = true; } else { window = reinterpret_cast<WindowImpl*>(GetWindowUserData(hwnd)); } if (!window) return 0; auto logger = CrashIdHelper::Get()->OnWillProcessMessages(window->debugging_id_); return window->OnWndProc(message, w_param, l_param); } |
ui_views.dll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
LRESULT HWNDMessageHandler::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) { HWND window = hwnd(); LRESULT result = 0; if (delegate_ && delegate_->PreHandleMSG(message, w_param, l_param, &result)) return result; const BOOL old_msg_handled = msg_handled_; base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr()); const BOOL processed = _ProcessWindowMessage(window, message, w_param, l_param, result, 0); if (!ref) return 0; msg_handled_ = old_msg_handled; if (!processed) { result = DefWindowProc(window, message, w_param, l_param); // DefWindowProc() may have destroyed the window and/or us in a nested // message loop. if (!ref || !::IsWindow(window)) return result; } // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
// _ProcessWindowMessage class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl, public ui::InputMethodObserver, public ui::WindowEventTarget, public ui::AXFragmentRootDelegateWin { // ... // Message Handlers -------------------------------------------------- CR_BEGIN_MSG_MAP_EX(HWNDMessageHandler) // Range handlers must go first! CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange) CR_MESSAGE_RANGE_HANDLER_EX(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnMouseRange) // CustomFrameWindow hacks CR_MESSAGE_HANDLER_EX(WM_NCUAHDRAWCAPTION, OnNCUAHDrawCaption) CR_MESSAGE_HANDLER_EX(WM_NCUAHDRAWFRAME, OnNCUAHDrawFrame) // Win 8.1 and newer CR_MESSAGE_HANDLER_EX(WM_DPICHANGED, OnDpiChanged) // Non-atlcrack.h handlers CR_MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject) // Mouse events. CR_MESSAGE_HANDLER_EX(WM_MOUSEACTIVATE, OnMouseActivate) CR_MESSAGE_HANDLER_EX(WM_MOUSELEAVE, OnMouseRange) CR_MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseRange) CR_MESSAGE_HANDLER_EX(WM_SETCURSOR, OnSetCursor); // Pointer events. CR_MESSAGE_HANDLER_EX(WM_POINTERACTIVATE, OnPointerActivate) CR_MESSAGE_HANDLER_EX(WM_POINTERDOWN, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_POINTERUP, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_POINTERUPDATE, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_POINTERENTER, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_POINTERLEAVE, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_NCPOINTERDOWN, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_NCPOINTERUP, OnPointerEvent) CR_MESSAGE_HANDLER_EX(WM_NCPOINTERUPDATE, OnPointerEvent) // Key events. CR_MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent) CR_MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent) CR_MESSAGE_HANDLER_EX(WM_SYSKEYDOWN, OnKeyEvent) CR_MESSAGE_HANDLER_EX(WM_SYSKEYUP, OnKeyEvent) CR_MESSAGE_HANDLER_EX(WM_INPUT, OnInputEvent) // IME Events. CR_MESSAGE_HANDLER_EX(WM_IME_SETCONTEXT, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_IME_STARTCOMPOSITION, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_IME_ENDCOMPOSITION, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_IME_REQUEST, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_IME_NOTIFY, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_CHAR, OnImeMessages) CR_MESSAGE_HANDLER_EX(WM_SYSCHAR, OnImeMessages) // Scroll events CR_MESSAGE_HANDLER_EX(WM_VSCROLL, OnScrollMessage) CR_MESSAGE_HANDLER_EX(WM_HSCROLL, OnScrollMessage) // Touch Events. CR_MESSAGE_HANDLER_EX(WM_TOUCH, OnTouchEvent) CR_MESSAGE_HANDLER_EX(WM_WINDOWSIZINGFINISHED, OnWindowSizingFinished) // Uses the general handler macro since the specific handler macro // MSG_WM_NCACTIVATE would convert WPARAM type to BOOL type. The high // word of WPARAM could be set when the window is minimized or restored. CR_MESSAGE_HANDLER_EX(WM_NCACTIVATE, OnNCActivate) // This list is in _ALPHABETICAL_ order! OR I WILL HURT YOU. CR_MSG_WM_ACTIVATEAPP(OnActivateApp) CR_MSG_WM_APPCOMMAND(OnAppCommand) CR_MSG_WM_CANCELMODE(OnCancelMode) CR_MSG_WM_CAPTURECHANGED(OnCaptureChanged) CR_MSG_WM_CLOSE(OnClose) CR_MSG_WM_COMMAND(OnCommand) CR_MSG_WM_CREATE(OnCreate) CR_MSG_WM_DESTROY(OnDestroy) CR_MSG_WM_DISPLAYCHANGE(OnDisplayChange) CR_MSG_WM_ENTERMENULOOP(OnEnterMenuLoop) CR_MSG_WM_EXITMENULOOP(OnExitMenuLoop) CR_MSG_WM_ENTERSIZEMOVE(OnEnterSizeMove) CR_MSG_WM_ERASEBKGND(OnEraseBkgnd) CR_MSG_WM_EXITSIZEMOVE(OnExitSizeMove) CR_MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo) CR_MSG_WM_INITMENU(OnInitMenu) CR_MSG_WM_INPUTLANGCHANGE(OnInputLangChange) CR_MSG_WM_KILLFOCUS(OnKillFocus) CR_MSG_WM_MOVE(OnMove) CR_MSG_WM_MOVING(OnMoving) CR_MSG_WM_NCCALCSIZE(OnNCCalcSize) CR_MSG_WM_NCCREATE(OnNCCreate) CR_MSG_WM_NCHITTEST(OnNCHitTest) CR_MSG_WM_NCPAINT(OnNCPaint) CR_MSG_WM_PAINT(OnPaint) CR_MSG_WM_SETFOCUS(OnSetFocus) CR_MSG_WM_SETICON(OnSetIcon) CR_MSG_WM_SETTEXT(OnSetText) CR_MSG_WM_SETTINGCHANGE(OnSettingChange) CR_MSG_WM_SIZE(OnSize) CR_MSG_WM_SIZING(OnSizing) CR_MSG_WM_SYSCOMMAND(OnSysCommand) CR_MSG_WM_THEMECHANGED(OnThemeChanged) CR_MSG_WM_TIMECHANGE(OnTimeChange) CR_MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged) CR_MSG_WM_WINDOWPOSCHANGING(OnWindowPosChanging) CR_END_MSG_MAP() // ... } |
1 2 3 4 5 6 |
LRESULT HWNDMessageHandler::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { return HandleMouseEventInternal(message, w_param, l_param, true); } |
- 这里把消息包装成event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message, WPARAM w_param, LPARAM l_param, bool track_mouse) { // ... if (message != WM_MOUSEWHEEL && message != WM_MOUSEHWHEEL && ui::IsMouseEventFromTouch(message)) { // ... } if (message == WM_MOUSEHWHEEL) last_mouse_hwheel_time_ = ::GetMessageTime(); if (message == WM_MOUSEWHEEL && ::GetMessageTime() == last_mouse_hwheel_time_) { message = WM_MOUSEHWHEEL; } if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) { // ... } else if (message == WM_NCLBUTTONDOWN && delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) { // ... } else if (message == WM_NCLBUTTONDOWN && delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) { // ... } else if (message == WM_NCRBUTTONDOWN && (w_param == HTCAPTION || w_param == HTSYSMENU)) { // ... } LONG message_time = GetMessageTime(); CHROME_MSG msg = {hwnd(), message, w_param, l_param, static_cast<DWORD>(message_time), {CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param)}}; ui::MouseEvent event(msg); if (IsSynthesizedMouseMessage(message, message_time, l_param)) event.set_flags(event.flags() | ui::EF_FROM_TOUCH); if (event.type() == ui::ET_MOUSE_MOVED && !HasCapture() && track_mouse) { // ... } else if (event.type() == ui::ET_MOUSE_EXITED) { // ... } else if (event.type() == ui::ET_MOUSEWHEEL) { // ... } if (using_wm_input_ && (event.type() == ui::ET_MOUSE_MOVED || event.type() == ui::ET_MOUSE_DRAGGED)) { return 0; } base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr()); bool handled = false; if (event.type() == ui::ET_MOUSE_DRAGGED) { // ... } else if (event.type() == ui::ET_MOUSE_PRESSED) { num_drag_events_after_press_ = 0; } if (!handling_mouse_menu_ || message != WM_RBUTTONUP) handled = delegate_->HandleMouseEvent(&event); // ... } |
1 2 3 4 5 6 7 8 |
bool DesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) { // Ignore native platform events for test purposes if (ui::PlatformEventSource::ShouldIgnoreNativePlatformEvents()) return true; SendEventToSink(event); return event->handled(); } |
ui_event.dll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
EventDispatchDetails EventSource::SendEventToSink(const Event* event) { return SendEventToSinkFromRewriter(event, nullptr); } EventDispatchDetails EventSource::SendEventToSinkFromRewriter( const Event* event, const EventRewriter* rewriter) { // ... if (rewriter) { // If a rewriter reposted |event|, only send it to subsequent rewriters. it = FindContinuation(rewriter); CHECK(it != rewriter_list_.end()); ++it; } if (it == rewriter_list_.end()) return DeliverEventToSink(const_cast<Event*>(event)); return (*it)->rewriter()->RewriteEvent(*event_for_rewriting, (*it)->GetWeakPtr()); } |
1 2 3 4 5 |
EventDispatchDetails EventSource::DeliverEventToSink(Event* event) { EventSink* sink = GetEventSink(); CHECK(sink); return sink->OnEventFromSource(event); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
EventDispatchDetails EventProcessor::OnEventFromSource(Event* event) { bool dispatch_original_event = event->phase() == EP_PREDISPATCH; DCHECK(dispatch_original_event || event->target()); Event* event_to_dispatch = event; std::unique_ptr<Event> event_copy; if (!dispatch_original_event) { event_copy = event->Clone(); event_to_dispatch = event_copy.get(); } EventDispatchDetails details; OnEventProcessingStarted(event_to_dispatch); EventTarget* target = nullptr; if (!event_to_dispatch->handled()) { // ... auto* new_event_sink = targeter->GetNewEventSinkForEvent(root, target, event_to_dispatch); if (new_event_sink) { std::ignore = new_event_sink->OnEventFromSource(event_to_dispatch); if (!weak_this) { details.dispatcher_destroyed = true; return details; } } else { while (target) { details = DispatchEvent(target, event_to_dispatch); // ... } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
EventDispatchDetails EventDispatcherDelegate::DispatchEvent(EventTarget* target, Event* event) { // ... EventDispatchDetails details = PreDispatchEvent(target, event); if (!event->handled() && !details.dispatcher_destroyed && !details.target_destroyed) { details = DispatchEventToTarget(target, event); } // ... } |
1 2 3 4 5 6 7 8 9 |
EventDispatchDetails EventDispatcherDelegate::DispatchEventToTarget( EventTarget* target, Event* event) { EventDispatcher* old_dispatcher = dispatcher_; EventDispatcher dispatcher(this); dispatcher_ = &dispatcher; dispatcher.ProcessEvent(target, event); // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
void EventDispatcher::ProcessEvent(EventTarget* target, Event* event) { if (!target || !target->CanAcceptEvent(*event)) return; ScopedDispatchHelper dispatch_helper(event); dispatch_helper.set_target(target); handler_list_.clear(); target->GetPreTargetHandlers(&handler_list_); dispatch_helper.set_phase(EP_PRETARGET); DispatchEventToEventHandlers(&handler_list_, event); // All pre-target handler should have been removed. CHECK(handler_list_.empty()); if (event->handled()) return; // DispatchEvent if (delegate_ && delegate_->CanDispatchToTarget(target) && target->target_handler()) { dispatch_helper.set_phase(EP_TARGET); DispatchEvent(target->target_handler(), event); if (event->handled()) return; } if (!delegate_ || !delegate_->CanDispatchToTarget(target)) return; target->GetPostTargetHandlers(&handler_list_); dispatch_helper.set_phase(EP_POSTTARGET); DispatchEventToEventHandlers(&handler_list_, event); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void EventDispatcher::DispatchEvent(EventHandler* handler, Event* event) { // If the target has been invalidated or deleted, don't dispatch the event. if (!delegate_->CanDispatchToTarget(event->target())) { if (event->cancelable()) event->StopPropagation(); return; } base::AutoReset<Event*> event_reset(¤t_event_, event); handler->OnEvent(event); if (!delegate_ && event->cancelable()) event->StopPropagation(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void EventHandler::OnEvent(Event* event) { // You may uncomment the following line if more detailed logging is necessary // for diagnosing event processing. This code is a critical path and the added // overhead from the logging can introduce other issues. Please do not commit // with the following line commented without first discussing with OWNERs. // See crbug/1210633 for details. // VLOG(5) << GetLogContext() << "::OnEvent(" << event->ToString() << ")"; if (event->IsKeyEvent()) OnKeyEvent(event->AsKeyEvent()); else if (event->IsMouseEvent()) OnMouseEvent(event->AsMouseEvent()); else if (event->IsScrollEvent()) OnScrollEvent(event->AsScrollEvent()); else if (event->IsTouchEvent()) OnTouchEvent(event->AsTouchEvent()); else if (event->IsGestureEvent()) OnGestureEvent(event->AsGestureEvent()); else if (event->IsCancelModeEvent()) OnCancelMode(event->AsCancelModeEvent()); } |
ui_views.dll
1 2 3 4 5 6 7 8 9 |
void DesktopNativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) { DCHECK(content_window_->IsVisible()); if (tooltip_manager_.get()) tooltip_manager_->UpdateTooltip(); TooltipManagerAura::UpdateTooltipManagerForCapture(this); if (native_widget_delegate_) native_widget_delegate_->OnMouseEvent(event); // WARNING: we may have been deleted. } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
void Widget::OnMouseEvent(ui::MouseEvent* event) { if (!native_widget_) return; TRACE_EVENT0("ui", "Widget::OnMouseEvent"); View* root_view = GetRootView(); switch (event->type()) { case ui::ET_MOUSE_PRESSED: { // ... } case ui::ET_MOUSE_RELEASED: last_mouse_event_was_move_ = false; is_mouse_button_pressed_ = false; // Release capture first, to avoid confusion if OnMouseReleased blocks. if (auto_release_capture_ && native_widget_->HasCapture()) { base::AutoReset<bool> resetter(&ignore_capture_loss_, true); native_widget_->ReleaseCapture(); } if (root_view) root_view->OnMouseReleased(*event); if ((event->flags() & ui::EF_IS_NON_CLIENT) == 0 && // If none of the "normal" buttons are pressed, this event may be from // one of the newer mice that have buttons bound to browser forward // back actions. Don't squelch the event and let the default handler // process it. (event->flags() & (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) event->SetHandled(); return; // ... } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void RootView::OnMouseReleased(const ui::MouseEvent& event) { UpdateCursor(event); if (mouse_pressed_handler_) { ui::MouseEvent mouse_released(event, static_cast<View*>(this), mouse_pressed_handler_.get()); // We allow the view to delete us from the event dispatch callback. As such, // configure state such that we're done first, then call View. View* mouse_pressed_handler = mouse_pressed_handler_; // During mouse event handling, `SetMouseAndGestureHandler()` may be called // to set the gesture handler. Therefore we should reset the gesture handler // when mouse is released. SetMouseAndGestureHandler(nullptr); ui::EventDispatchDetails dispatch_details = DispatchEvent(mouse_pressed_handler, &mouse_released); if (dispatch_details.dispatcher_destroyed) return; } } |
ui_event.dll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
EventDispatchDetails EventDispatcherDelegate::DispatchEvent(EventTarget* target, Event* event) { CHECK(target); Event::DispatcherApi dispatch_helper(event); dispatch_helper.set_phase(EP_PREDISPATCH); dispatch_helper.set_result(ER_UNHANDLED); EventDispatchDetails details = PreDispatchEvent(target, event); if (!event->handled() && !details.dispatcher_destroyed && !details.target_destroyed) { details = DispatchEventToTarget(target, event); } bool target_destroyed_during_dispatch = details.target_destroyed; if (!details.dispatcher_destroyed) { details = PostDispatchEvent(target_destroyed_during_dispatch ? NULL : target, *event); } details.target_destroyed |= target_destroyed_during_dispatch; return details; } |
1 2 3 4 5 6 7 8 9 |
EventDispatchDetails EventDispatcherDelegate::DispatchEventToTarget( EventTarget* target, Event* event) { EventDispatcher* old_dispatcher = dispatcher_; EventDispatcher dispatcher(this); dispatcher_ = &dispatcher; dispatcher.ProcessEvent(target, event); // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void EventDispatcher::ProcessEvent(EventTarget* target, Event* event) { // ... if (delegate_ && delegate_->CanDispatchToTarget(target) && target->target_handler()) { dispatch_helper.set_phase(EP_TARGET); DispatchEvent(target->target_handler(), event); if (event->handled()) return; } // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 |
void EventDispatcher::DispatchEvent(EventHandler* handler, Event* event) { if (!delegate_->CanDispatchToTarget(event->target())) { if (event->cancelable()) event->StopPropagation(); return; } base::AutoReset<Event*> event_reset(¤t_event_, event); handler->OnEvent(event); if (!delegate_ && event->cancelable()) event->StopPropagation(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void ScopedTargetHandler::OnEvent(Event* event) { if (original_handler_) { auto weak_this = weak_factory_.GetWeakPtr(); original_handler_->OnEvent(event); if (!weak_this) return; } // This check is needed due to nested event loops when starting DragDrop. if (event->stopped_propagation()) return; new_handler_->OnEvent(event); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void EventHandler::OnEvent(Event* event) { // You may uncomment the following line if more detailed logging is necessary // for diagnosing event processing. This code is a critical path and the added // overhead from the logging can introduce other issues. Please do not commit // with the following line commented without first discussing with OWNERs. // See crbug/1210633 for details. // VLOG(5) << GetLogContext() << "::OnEvent(" << event->ToString() << ")"; if (event->IsKeyEvent()) OnKeyEvent(event->AsKeyEvent()); else if (event->IsMouseEvent()) OnMouseEvent(event->AsMouseEvent()); else if (event->IsScrollEvent()) OnScrollEvent(event->AsScrollEvent()); else if (event->IsTouchEvent()) OnTouchEvent(event->AsTouchEvent()); else if (event->IsGestureEvent()) OnGestureEvent(event->AsGestureEvent()); else if (event->IsCancelModeEvent()) OnCancelMode(event->AsCancelModeEvent()); } |
ui_views.dll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
void View::OnMouseEvent(ui::MouseEvent* event) { switch (event->type()) { case ui::ET_MOUSE_PRESSED: if (ProcessMousePressed(*event)) event->SetHandled(); return; case ui::ET_MOUSE_MOVED: if ((event->flags() & (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON)) == 0) { OnMouseMoved(*event); return; } [[fallthrough]]; case ui::ET_MOUSE_DRAGGED: ProcessMouseDragged(event); return; // 这 case ui::ET_MOUSE_RELEASED: ProcessMouseReleased(*event); return; case ui::ET_MOUSEWHEEL: if (OnMouseWheel(*event->AsMouseWheelEvent())) event->SetHandled(); break; case ui::ET_MOUSE_ENTERED: if (event->flags() & ui::EF_TOUCH_ACCESSIBILITY) NotifyAccessibilityEvent(ax::mojom::Event::kHover, true); OnMouseEntered(*event); break; case ui::ET_MOUSE_EXITED: OnMouseExited(*event); break; default: return; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void View::ProcessMouseReleased(const ui::MouseEvent& event) { if (!kContextMenuOnMousePress && context_menu_controller_ && event.IsOnlyRightMouseButton()) { // Assume that if there is a context menu controller we won't be deleted // from mouse released. gfx::Point location(event.location()); OnMouseReleased(event); if (HitTestPoint(location)) { ConvertPointToScreen(this, &location); ShowContextMenu(location, ui::MENU_SOURCE_MOUSE); } } else { OnMouseReleased(event); } // WARNING: we may have been deleted. } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
void ToolbarButton::OnMouseReleased(const ui::MouseEvent& event) { if (IsTriggerableEvent(event) || (event.IsRightMouseButton() && !HitTestPoint(event.location()))) { LabelButton::OnMouseReleased(event); } if (IsTriggerableEvent(event)) show_menu_factory_.InvalidateWeakPtrs(); } void Button::OnMouseReleased(const ui::MouseEvent& event) { button_controller_->OnMouseReleased(event); } void ButtonController::OnMouseReleased(const ui::MouseEvent& event) { if (button_->GetState() != Button::STATE_DISABLED) { if (!button_->HitTestPoint(event.location())) { button_->SetState(Button::STATE_NORMAL); } else { button_->SetState(Button::STATE_HOVERED); if (button_controller_delegate_->IsTriggerableEvent(event) && notify_action_ == ButtonController::NotifyAction::kOnRelease) { // 这里 button_controller_delegate_->NotifyClick(event); // NOTE: We may be deleted at this point (by the listener's notification // handler). return; } } } if (notify_action_ == ButtonController::NotifyAction::kOnRelease) button_controller_delegate_->OnClickCanceled(event); } void Button::DefaultButtonControllerDelegate::NotifyClick( const ui::Event& event) { button()->NotifyClick(event); // Avoid outgoing tail calls to generate better stack frames for a crash. // https://crbug.com/1215247 base::debug::Alias(nullptr); if (element_id) { views::ElementTrackerViews::GetInstance()->NotifyViewActivated(element_id, this); } if (callback_) callback_.Run(event); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class VIEWS_EXPORT PressedCallback { // ... void Run(const ui::Event& event) { callback_.Run(event); } // ... } R Run(Args... args) const& { // Keep `bind_state` alive at least until after the invocation to ensure all // bound `Unretained` arguments remain protected by MiraclePtr. scoped_refptr<internal::BindStateBase> bind_state = holder_.bind_state(); PolymorphicInvoke f = reinterpret_cast<PolymorphicInvoke>(holder_.polymorphic_invoke()); return f(bind_state.get(), std::forward<Args>(args)...); } |
chrome.dll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) { // Local references to make debugger stepping easier. If in a debugger, // you really want to warp ahead and step through the // InvokeHelper<>::MakeItSo() call below. const StorageType* storage = static_cast<StorageType*>(base); static constexpr size_t num_bound_args = std::tuple_size_v<decltype(storage->bound_args_)>; return RunImpl(storage->functor_, storage->bound_args_, std::make_index_sequence<num_bound_args>(), std::forward<UnboundArgs>(unbound_args)...); } static inline R RunImpl(Functor&& functor, BoundArgsTuple&& bound, std::index_sequence<indices...> seq, UnboundArgs&&... unbound_args) { // ... return InvokeHelper<is_weak_call, R, indices...>::MakeItSo( std::forward<Functor>(functor), std::forward<BoundArgsTuple>(bound), std::forward<UnboundArgs>(unbound_args)...); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
template <typename ReturnType, size_t... indices> struct InvokeHelper<false, ReturnType, indices...> { template <typename Functor, typename BoundArgsTuple, typename... RunArgs> static inline ReturnType MakeItSo(Functor&& functor, BoundArgsTuple&& bound, RunArgs&&... args) { using Traits = MakeFunctorTraits<Functor>; return Traits::Invoke( std::forward<Functor>(functor), Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., std::forward<RunArgs>(args)...); } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// For methods. template <typename R, typename Receiver, typename... Args> struct FunctorTraits<R (Receiver::*)(Args...)> { using RunType = R(Receiver*, Args...); static constexpr bool is_method = true; static constexpr bool is_nullable = true; static constexpr bool is_callback = false; static constexpr bool is_stateless = true; template <typename Method, typename ReceiverPtr, typename... RunArgs> static R Invoke(Method method, ReceiverPtr&& receiver_ptr, RunArgs&&... args) { return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
void ReloadButton::ButtonPressed(const ui::Event& event) { ExternalProtocolHandler::PermitLaunchUrl(); ClearPendingMenu(); if (visible_mode_ == Mode::kStop) { if (command_updater_) { command_updater_->ExecuteCommandWithDisposition( IDC_STOP, WindowOpenDisposition::CURRENT_TAB); } // The user has clicked, so we can feel free to update the button, even if // the mouse is still hovering. ChangeMode(Mode::kReload, true); return; } if (!double_click_timer_.IsRunning()) { // Shift-clicking or ctrl-clicking the reload button means we should ignore // any cached content. int command; int flags = event.flags(); if (event.IsShiftDown() || event.IsControlDown()) { command = IDC_RELOAD_BYPASSING_CACHE; // Mask off Shift and Control so they don't affect the disposition below. flags &= ~(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); } else { command = IDC_RELOAD; } // Start a timer - while this timer is running, the reload button cannot be // changed to a stop button. We do not set |intended_mode_| to Mode::kStop // here as the browser will do that when it actually starts loading (which // may happen synchronously, thus the need to do this before telling the // browser to execute the reload command). double_click_timer_.Start(FROM_HERE, double_click_timer_delay_, this, &ReloadButton::OnDoubleClickTimer); ExecuteBrowserCommand(command, flags); ++testing_reload_count_; } } void ReloadButton::ExecuteBrowserCommand(int command, int event_flags) { if (!command_updater_) return; command_updater_->ExecuteCommandWithDisposition( command, ui::DispositionFromEventFlags(event_flags)); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
bool BrowserCommandController::ExecuteCommandWithDisposition( int id, WindowOpenDisposition disposition, base::TimeTicks time_stamp) { if (!SupportsCommand(id) || !IsCommandEnabled(id)) { return false; } if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab) return true; switch (id) { // Navigation commands case IDC_BACK: GoBack(browser_, disposition); break; case IDC_FORWARD: GoForward(browser_, disposition); break; case IDC_RELOAD: Reload(browser_, disposition); break; case IDC_RELOAD_CLEARING_CACHE: ClearCache(browser_); [[fallthrough]]; case IDC_RELOAD_BYPASSING_CACHE: ReloadBypassingCache(browser_, disposition); break; case IDC_HOME: Home(browser_, disposition); break; case IDC_OPEN_CURRENT_URL: OpenCurrentURL(browser_); break; case IDC_STOP: Stop(browser_); break; case IDC_TAB_SEARCH: ShowTabSearch(browser_); break; case IDC_TAB_SEARCH_CLOSE: CloseTabSearch(browser_); break; // Window management commands case IDC_NEW_WINDOW: NewWindow(browser_); break; case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(profile()); break; case IDC_CLOSE_WINDOW: base::RecordAction(base::UserMetricsAction("CloseWindowByKey")); CloseWindow(browser_); break; case IDC_NEW_TAB: { NewTab(browser_); break; } case IDC_NEW_TAB_TO_RIGHT: { NewTabToRight(browser_); break; } case IDC_CLOSE_TAB: base::RecordAction(base::UserMetricsAction("CloseTabByKey")); CloseTab(browser_); break; case IDC_SELECT_NEXT_TAB: base::RecordAction(base::UserMetricsAction("Accel_SelectNextTab")); SelectNextTab( browser_, TabStripUserGestureDetails( TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); break; case IDC_SELECT_PREVIOUS_TAB: base::RecordAction(base::UserMetricsAction("Accel_SelectPreviousTab")); SelectPreviousTab( browser_, TabStripUserGestureDetails( TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); break; case IDC_MOVE_TAB_NEXT: MoveTabNext(browser_); break; case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(browser_); break; case IDC_SELECT_TAB_0: case IDC_SELECT_TAB_1: case IDC_SELECT_TAB_2: case IDC_SELECT_TAB_3: case IDC_SELECT_TAB_4: case IDC_SELECT_TAB_5: case IDC_SELECT_TAB_6: case IDC_SELECT_TAB_7: base::RecordAction(base::UserMetricsAction("Accel_SelectNumberedTab")); SelectNumberedTab( browser_, id - IDC_SELECT_TAB_0, TabStripUserGestureDetails( TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); break; case IDC_SELECT_LAST_TAB: base::RecordAction(base::UserMetricsAction("Accel_SelectNumberedTab")); SelectLastTab( browser_, TabStripUserGestureDetails( TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); break; case IDC_DUPLICATE_TAB: DuplicateTab(browser_); break; case IDC_RESTORE_TAB: RestoreTab(browser_); break; case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(browser_); break; case IDC_FULLSCREEN: chrome::ToggleFullscreenMode(browser_); break; case IDC_OPEN_IN_PWA_WINDOW: base::RecordAction(base::UserMetricsAction("OpenActiveTabInPwaWindow")); web_app::ReparentWebAppForActiveTab(browser_); break; case IDC_MOVE_TAB_TO_NEW_WINDOW: MoveActiveTabToNewWindow(browser_); break; case IDC_NAME_WINDOW: PromptToNameWindow(browser_); break; #if BUILDFLAG(IS_CHROMEOS) case IDC_TOGGLE_MULTITASK_MENU: ToggleMultitaskMenu(browser_); break; #endif #if BUILDFLAG(IS_CHROMEOS_ASH) case IDC_VISIT_DESKTOP_OF_LRU_USER_2: case IDC_VISIT_DESKTOP_OF_LRU_USER_3: case IDC_VISIT_DESKTOP_OF_LRU_USER_4: case IDC_VISIT_DESKTOP_OF_LRU_USER_5: ExecuteVisitDesktopCommand(id, window()->GetNativeWindow()); break; #endif // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) case IDC_MINIMIZE_WINDOW: browser_->window()->Minimize(); break; case IDC_MAXIMIZE_WINDOW: browser_->window()->Maximize(); break; case IDC_RESTORE_WINDOW: browser_->window()->Restore(); break; #endif #if BUILDFLAG(IS_LINUX) case IDC_USE_SYSTEM_TITLE_BAR: { PrefService* prefs = profile()->GetPrefs(); prefs->SetBoolean(prefs::kUseCustomChromeFrame, !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); break; } #endif #if BUILDFLAG(IS_MAC) case IDC_TOGGLE_FULLSCREEN_TOOLBAR: chrome::ToggleFullscreenToolbar(browser_); break; case IDC_TOGGLE_JAVASCRIPT_APPLE_EVENTS: { chrome::ToggleJavaScriptFromAppleEventsAllowed(browser_); break; } #endif case IDC_EXIT: Exit(); break; // Page-related commands case IDC_SAVE_PAGE: SavePage(browser_); break; case IDC_BOOKMARK_THIS_TAB: BookmarkCurrentTab(browser_); break; case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(browser_); break; case IDC_VIEW_SOURCE: browser_->tab_strip_model() ->GetActiveWebContents() ->GetPrimaryMainFrame() ->ViewSource(); break; case IDC_PRINT: Print(browser_); break; #if BUILDFLAG(ENABLE_PRINTING) case IDC_BASIC_PRINT: base::RecordAction(base::UserMetricsAction("Accel_Advanced_Print")); BasicPrint(browser_); break; #endif // ENABLE_PRINTING case IDC_OFFERS_AND_REWARDS_FOR_PAGE: ShowOffersAndRewardsForPage(browser_); break; case IDC_SAVE_CREDIT_CARD_FOR_PAGE: SaveCreditCard(browser_); break; case IDC_SAVE_IBAN_FOR_PAGE: SaveIBAN(browser_); break; case IDC_AUTOFILL_MANDATORY_REAUTH: ShowMandatoryReauthOptInPrompt(browser_); break; case IDC_MIGRATE_LOCAL_CREDIT_CARD_FOR_PAGE: MigrateLocalCards(browser_); break; case IDC_SAVE_AUTOFILL_ADDRESS: SaveAutofillAddress(browser_); break; case IDC_SHOW_SYNC_SETTINGS: chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage); break; case IDC_TURN_ON_SYNC: signin_ui_util::EnableSyncFromSingleAccountPromo( browser_->profile(), GetAccountInfoFromProfile(browser_->profile()), signin_metrics::AccessPoint::ACCESS_POINT_MENU); break; case IDC_SHOW_SIGNIN_WHEN_PAUSED: signin_ui_util::ShowReauthForPrimaryAccountWithAuthError( browser_->profile(), signin_metrics::AccessPoint::ACCESS_POINT_MENU); break; case IDC_SHOW_PASSWORD_MANAGER: ShowPasswordManager(browser_); break; case IDC_SHOW_PAYMENT_METHODS: ShowPaymentMethods(browser_); break; case IDC_SHOW_ADDRESSES: ShowAddresses(browser_); break; case IDC_VIRTUAL_CARD_MANUAL_FALLBACK: ShowVirtualCardManualFallbackBubble(browser_); break; case IDC_VIRTUAL_CARD_ENROLL: ShowVirtualCardEnrollBubble(browser_); break; case IDC_SHOW_TRANSLATE: ShowTranslateBubble(browser_); break; case IDC_MANAGE_PASSWORDS_FOR_PAGE: ManagePasswordsForPage(browser_); break; case IDC_SEND_TAB_TO_SELF: SendTabToSelfFromPageAction(browser_); break; case IDC_QRCODE_GENERATOR: GenerateQRCodeFromPageAction(browser_); break; case IDC_SHARING_HUB: SharingHubFromPageAction(browser_); break; case IDC_SHARING_HUB_SCREENSHOT: ScreenshotCaptureFromPageAction(browser_); break; case IDC_FOLLOW: FollowSite(browser_->tab_strip_model()->GetActiveWebContents()); break; case IDC_UNFOLLOW: UnfollowSite(browser_->tab_strip_model()->GetActiveWebContents()); break; // Clipboard commands case IDC_CUT: case IDC_COPY: case IDC_PASTE: CutCopyPaste(browser_, id); break; // Find-in-page case IDC_FIND: Find(browser_); break; case IDC_FIND_NEXT: FindNext(browser_); break; case IDC_FIND_PREVIOUS: FindPrevious(browser_); break; case IDC_CLOSE_FIND_OR_STOP: if (CanCloseFind(browser_)) CloseFind(browser_); else if (IsCommandEnabled(IDC_STOP)) ExecuteCommand(IDC_STOP); break; // Zoom case IDC_ZOOM_PLUS: Zoom(browser_, content::PAGE_ZOOM_IN); break; case IDC_ZOOM_NORMAL: Zoom(browser_, content::PAGE_ZOOM_RESET); break; case IDC_ZOOM_MINUS: Zoom(browser_, content::PAGE_ZOOM_OUT); break; // Focus various bits of UI case IDC_FOCUS_TOOLBAR: base::RecordAction(base::UserMetricsAction("Accel_Focus_Toolbar")); FocusToolbar(browser_); break; case IDC_FOCUS_LOCATION: if (!window()->IsLocationBarVisible()) break; base::RecordAction(base::UserMetricsAction("Accel_Focus_Location")); FocusLocationBar(browser_); break; case IDC_FOCUS_SEARCH: base::RecordAction(base::UserMetricsAction("Accel_Focus_Search")); FocusSearch(browser_); break; case IDC_FOCUS_MENU_BAR: FocusAppMenu(browser_); break; case IDC_FOCUS_BOOKMARKS: base::RecordAction(base::UserMetricsAction("Accel_Focus_Bookmarks")); FocusBookmarksToolbar(browser_); break; case IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY: FocusInactivePopupForAccessibility(browser_); break; case IDC_FOCUS_NEXT_PANE: FocusNextPane(browser_); break; case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(browser_); break; case IDC_FOCUS_WEB_CONTENTS_PANE: FocusWebContentsPane(browser_); break; // Show various bits of UI case IDC_OPEN_FILE: browser_->OpenFile(); break; case IDC_CREATE_SHORTCUT: base::RecordAction(base::UserMetricsAction("CreateShortcut")); web_app::CreateWebAppFromCurrentWebContents( browser_, web_app::WebAppInstallFlow::kCreateShortcut); break; case IDC_INSTALL_PWA: base::RecordAction(base::UserMetricsAction("InstallWebAppFromMenu")); web_app::CreateWebAppFromCurrentWebContents( browser_, web_app::WebAppInstallFlow::kInstallSite); break; case IDC_DEV_TOOLS: ToggleDevToolsWindow(browser_, DevToolsToggleAction::Show(), DevToolsOpenedByAction::kMainMenuOrMainShortcut); break; case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(browser_, DevToolsToggleAction::ShowConsolePanel(), DevToolsOpenedByAction::kConsoleShortcut); break; case IDC_DEV_TOOLS_DEVICES: InspectUI::InspectDevices(browser_); break; case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(browser_, DevToolsToggleAction::Inspect(), DevToolsOpenedByAction::kInspectorModeShortcut); break; case IDC_DEV_TOOLS_TOGGLE: ToggleDevToolsWindow(browser_, DevToolsToggleAction::Toggle(), DevToolsOpenedByAction::kToggleShortcut); break; case IDC_TASK_MANAGER: OpenTaskManager(browser_); break; #if BUILDFLAG(IS_CHROMEOS_ASH) case IDC_TAKE_SCREENSHOT: TakeScreenshot(); break; #endif #if BUILDFLAG(GOOGLE_CHROME_BRANDING) case IDC_FEEDBACK: OpenFeedbackDialog(browser_, kFeedbackSourceBrowserCommand); break; case IDC_SHOW_SEARCH_COMPANION: SidePanelUI::GetSidePanelUIForBrowser(browser_)->Show( SidePanelEntryId::kSearchCompanion, SidePanelOpenTrigger::kAppMenu); break; #endif case IDC_SHOW_CHROME_LABS: window()->ShowChromeLabs(); break; case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(browser_); break; case IDC_SHOW_FULL_URLS: ToggleShowFullURLs(browser_); break; case IDC_PROFILING_ENABLED: content::Profiling::Toggle(); break; case IDC_CARET_BROWSING_TOGGLE: ToggleCaretBrowsing(browser_); break; case IDC_RECENT_TABS_LOGIN_FOR_DEVICE_TABS: ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(), chrome::kPeopleSubPage); break; case IDC_SHOW_BOOKMARK_MANAGER: ShowBookmarkManager(browser_->GetBrowserForOpeningWebUi()); break; case IDC_SHOW_BOOKMARK_SIDE_PANEL: SidePanelUI::GetSidePanelUIForBrowser(browser_)->Show( SidePanelEntryId::kBookmarks, SidePanelOpenTrigger::kAppMenu); break; case IDC_SHOW_APP_MENU: base::RecordAction(base::UserMetricsAction("Accel_Show_App_Menu")); ShowAppMenu(browser_); break; case IDC_SHOW_AVATAR_MENU: ShowAvatarMenu(browser_); break; case IDC_SHOW_HISTORY: ShowHistory(browser_->GetBrowserForOpeningWebUi()); break; case IDC_SHOW_DOWNLOADS: ShowDownloads(browser_->GetBrowserForOpeningWebUi()); break; case IDC_MANAGE_EXTENSIONS: ShowExtensions(browser_->GetBrowserForOpeningWebUi()); break; case IDC_EXTENSIONS_SUBMENU_MANAGE_EXTENSIONS: CHECK(base::FeatureList::IsEnabled(features::kExtensionsMenuInAppMenu) || features::IsChromeRefresh2023()); ShowExtensions(browser_->GetBrowserForOpeningWebUi()); break; case IDC_EXTENSIONS_SUBMENU_VISIT_CHROME_WEB_STORE: CHECK(base::FeatureList::IsEnabled(features::kExtensionsMenuInAppMenu) || features::IsChromeRefresh2023()); ShowWebStore(browser_, extension_urls::kAppMenuUtmSource); break; case IDC_PERFORMANCE: ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(), chrome::kPerformanceSubPage); break; case IDC_OPTIONS: ShowSettings(browser_->GetBrowserForOpeningWebUi()); break; case IDC_EDIT_SEARCH_ENGINES: ShowSearchEngineSettings(browser_->GetBrowserForOpeningWebUi()); break; case IDC_VIEW_PASSWORDS: NavigateToManagePasswordsPage( browser_->GetBrowserForOpeningWebUi(), password_manager::ManagePasswordsReferrer::kChromeMenuItem); break; case IDC_CLEAR_BROWSING_DATA: { if (profile()->IsIncognitoProfile()) { ShowIncognitoClearBrowsingDataDialog( browser_->GetBrowserForOpeningWebUi()); } else { ShowClearBrowsingDataDialog(browser_->GetBrowserForOpeningWebUi()); } break; } case IDC_IMPORT_SETTINGS: ShowImportDialog(browser_); break; case IDC_TOGGLE_REQUEST_TABLET_SITE: ToggleRequestTabletSite(browser_); break; case IDC_ABOUT: ShowAboutChrome(browser_->GetBrowserForOpeningWebUi()); break; case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(browser_); break; #if BUILDFLAG(IS_CHROMEOS_ASH) case IDC_LACROS_DATA_MIGRATION: { auto* user_manager = user_manager::UserManager::Get(); const auto* user = user_manager->GetPrimaryUser(); DCHECK(user); // Unset local state holding the internal state of the previous migration // attempts used to avoid the infinite loop of the migration. // Because user explicitly triggered the migration so we should try to // run it always. ash::BrowserDataMigratorImpl::ClearMigrationStep( user_manager->GetLocalState()); ash::BrowserDataMigratorImpl::ClearMigrationAttemptCountForUser( user_manager->GetLocalState(), user->username_hash()); ash::BrowserDataMigratorImpl::MaybeRestartToMigrateWithDiskCheck( user->GetAccountId(), user->username_hash(), base::BindOnce( [](bool result, const absl::optional<uint64_t>& required_size) { if (!result && required_size.has_value()) ash::OpenBrowserDataMigrationErrorDialog(*required_size); })); break; } #endif // BUILDFLAG(IS_CHROMEOS_ASH) case IDC_HELP_PAGE_VIA_KEYBOARD: ShowHelp(browser_, HELP_SOURCE_KEYBOARD); break; case IDC_HELP_PAGE_VIA_MENU: ShowHelp(browser_, HELP_SOURCE_MENU); break; case IDC_CHROME_TIPS: #if BUILDFLAG(GOOGLE_CHROME_BRANDING) ShowChromeTips(browser_); #else NOTREACHED(); #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) break; case IDC_CHROME_WHATS_NEW: #if BUILDFLAG(GOOGLE_CHROME_BRANDING) ShowChromeWhatsNew(browser_); #else NOTREACHED(); #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) break; case IDC_SHOW_BETA_FORUM: ShowBetaForum(browser_); break; case IDC_TOGGLE_QUICK_COMMANDS: ToggleCommander(browser_); break; case IDC_DISTILL_PAGE: ToggleDistilledView(browser_); break; case IDC_ROUTE_MEDIA: RouteMediaInvokedFromAppMenu(browser_); break; case IDC_WINDOW_MUTE_SITE: MuteSite(browser_); break; case IDC_WINDOW_PIN_TAB: PinTab(browser_); break; case IDC_WINDOW_GROUP_TAB: GroupTab(browser_); break; case IDC_WINDOW_CLOSE_TABS_TO_RIGHT: CloseTabsToRight(browser_); break; case IDC_WINDOW_CLOSE_OTHER_TABS: CloseOtherTabs(browser_); break; case IDC_SHOW_MANAGEMENT_PAGE: { ShowSingletonTab(browser_, GetManagedUiUrl(profile())); break; } case IDC_MUTE_TARGET_SITE: MuteSiteForKeyboardFocusedTab(browser_); break; case IDC_PIN_TARGET_TAB: PinKeyboardFocusedTab(browser_); break; case IDC_GROUP_TARGET_TAB: GroupKeyboardFocusedTab(browser_); break; case IDC_DUPLICATE_TARGET_TAB: DuplicateKeyboardFocusedTab(browser_); break; // Hosted App commands case IDC_COPY_URL: CopyURL(browser_->tab_strip_model()->GetActiveWebContents()); break; case IDC_OPEN_IN_CHROME: OpenInChrome(browser_); break; case IDC_WEB_APP_SETTINGS: #if !BUILDFLAG(IS_CHROMEOS) CHECK(browser_->app_controller()); ShowWebAppSettings(browser_, browser_->app_controller()->app_id(), web_app::AppSettingsPageEntryPoint::kBrowserCommand); #endif break; case IDC_WEB_APP_MENU_APP_INFO: { content::WebContents* const web_contents = browser_->tab_strip_model()->GetActiveWebContents(); if (web_contents) { ShowPageInfoDialog( web_contents, base::BindOnce(&AppInfoDialogClosedCallback, sessions::SessionTabHelper::IdForWindowContainingTab( web_contents)), bubble_anchor_util::kAppMenuButton); } break; } // UI debug commands case IDC_DEBUG_TOGGLE_TABLET_MODE: case IDC_DEBUG_PRINT_VIEW_TREE: case IDC_DEBUG_PRINT_VIEW_TREE_DETAILS: ExecuteUIDebugCommand(id, browser_); break; #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) case IDC_RUN_SCREEN_AI_VISUAL_ANNOTATIONS: RunScreenAIVisualAnnotation(browser_); break; #endif #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) case IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH: ExecLensRegionSearch(browser_); break; #endif // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) case IDC_READING_LIST_MENU_ADD_TAB: chrome::MoveCurrentTabToReadLater(browser_); break; case IDC_READING_LIST_MENU_SHOW_UI: SidePanelUI::GetSidePanelUIForBrowser(browser_)->Show( SidePanelEntryId::kReadingList, SidePanelOpenTrigger::kAppMenu); break; #if !BUILDFLAG(IS_CHROMEOS_ASH) // Profile submenu commands // This menu item is not enabled on ChromeOS and certain capabilities such // as the profile picker are not available. case IDC_CUSTOMIZE_CHROME: chrome::ShowSettingsSubPage(browser_, chrome::kManageProfileSubPage); break; case IDC_CLOSE_PROFILE: { if (browser_->profile()->IsIncognitoProfile()) { BrowserList::CloseAllBrowsersWithIncognitoProfile( browser_->profile(), base::DoNothing(), base::DoNothing(), true); } else { profiles::CloseProfileWindows(browser_->profile()); } break; } case IDC_MANAGE_GOOGLE_ACCOUNT: { Profile* profile = browser_->profile(); signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); DCHECK( identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)); NavigateToGoogleAccountPage( profile, identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin) .email); break; } case IDC_OPEN_GUEST_PROFILE: profiles::SwitchToGuestProfile(); break; case IDC_ADD_NEW_PROFILE: ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint( ProfilePicker::EntryPoint::kAppMenuProfileSubMenuAddNewProfile)); break; case IDC_MANAGE_CHROME_PROFILES: ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint( ProfilePicker::EntryPoint::kAppMenuProfileSubMenuManageProfiles)); break; #endif // BUILDFLAG(IS_CHROMEOS_ASH) default: LOG(WARNING) << "Received Unimplemented Command: " << id; break; } return true; } |
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!