From a8995fbf1aab58eda9ecd1018d74734344daa5eb Mon Sep 17 00:00:00 2001 From: Kamal Umudlu Date: Fri, 8 Mar 2019 00:18:22 -0500 Subject: [PATCH] Bug: #22853 - Make Window::set_fullscreen pass a non-None value when entering fullscreen is fixed and SetFullscreenState in exit_fullscreen changed to False Added patch for bug:22853 Added implementation to exit from fullscreen mode by pressing ESC button Added patch that supports to exit from fullscreen mode by pressing ESC Deleted patch files Added all requested changes on project Removed the loop over self.pending_changes in switch_fullscreen_mode function Bug #22853 - Make Window::set_fullscreen pass a non-None value when entering fullscreen is fixed and SetFullscreenState in exit_fullscreen changed to False Added missing bracket in constellation.rs file to fix build issue Bug: #22853 --> Make Window::set_fullscreen pass a non-None value when entering fullscreen is fixed and SetFullscreenState in exit_fullscreen changed to False --- components/compositing/windowing.rs | 3 +++ components/constellation/constellation.rs | 31 +++++++++++++++++++++++ components/script/dom/document.rs | 2 +- components/script/script_thread.rs | 19 ++++++++++++++ components/script_traits/lib.rs | 6 +++++ components/servo/lib.rs | 7 +++++ ports/servo/browser.rs | 10 +++++++- ports/servo/glutin_app/window.rs | 6 ++++- 8 files changed, 81 insertions(+), 3 deletions(-) diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 7afcdde9a47..6105531bf85 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -78,6 +78,8 @@ pub enum WindowEvent { Navigation(TopLevelBrowsingContextId, TraversalDirection), /// Sent when the user quits the application Quit, + /// Sent when the user exits from fullscreen mode + ExitFullScreen(TopLevelBrowsingContextId), /// Sent when a key input state changes Keyboard(KeyboardEvent), /// Sent when Ctr+R/Apple+R is called to reload the current page. @@ -125,6 +127,7 @@ impl Debug for WindowEvent { WindowEvent::ToggleWebRenderDebug(..) => write!(f, "ToggleWebRenderDebug"), WindowEvent::CaptureWebRender => write!(f, "CaptureWebRender"), WindowEvent::ToggleSamplingProfiler(..) => write!(f, "ToggleSamplingProfiler"), + WindowEvent::ExitFullScreen(..) => write!(f, "ExitFullScreen"), } } } diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 3b440bdde82..835f4488cf7 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -1230,6 +1230,9 @@ where } } }, + FromCompositorMsg::ExitFullScreen(top_level_browsing_context_id) => { + self.handle_exit_fullscreen_msg(top_level_browsing_context_id); + }, } } @@ -3664,6 +3667,15 @@ where self.window_size = new_size; } + /// Called when the window exits from fullscreen mode + fn handle_exit_fullscreen_msg( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + ) { + let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); + self.switch_fullscreen_mode(browsing_context_id); + } + /// Handle updating actual viewport / zoom due to @viewport rules fn handle_viewport_constrained_msg( &mut self, @@ -3900,6 +3912,25 @@ where } } + // Handle switching from fullscreen mode + fn switch_fullscreen_mode(&mut self, browsing_context_id: BrowsingContextId) { + if let Some(browsing_context) = self.browsing_contexts.get(&browsing_context_id) { + let pipeline_id = browsing_context.pipeline_id; + let pipeline = match self.pipelines.get(&pipeline_id) { + None => { + return warn!( + "Pipeline {:?} switched from fullscreen mode after closing.", + pipeline_id + ) + }, + Some(pipeline) => pipeline, + }; + let _ = pipeline + .event_loop + .send(ConstellationControlMsg::ExitFullScreen(pipeline.id)); + } + } + // Close a browsing context (and all children) fn close_browsing_context( &mut self, diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index b59f9502d63..b3f08964502 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3211,7 +3211,7 @@ impl Document { let window = self.window(); // Step 8 - let event = EmbedderMsg::SetFullscreenState(true); + let event = EmbedderMsg::SetFullscreenState(false); self.send_to_embedder(event); // Step 9 diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 41a7192e70a..78b7a8606b0 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1304,6 +1304,10 @@ impl ScriptThread { // An event came-in from a document that is not fully-active, it has been stored by the task-queue. // Continue without adding it to "sequential". }, + FromConstellation(ConstellationControlMsg::ExitFullScreen(id)) => self + .profile_event(ScriptThreadEventCategory::ExitFullscreen, Some(id), || { + self.handle_exit_fullscreen(id); + }), _ => { sequential.push(event); }, @@ -1500,6 +1504,7 @@ impl ScriptThread { Reload(id, ..) => Some(id), WebVREvents(id, ..) => Some(id), PaintMetric(..) => None, + ExitFullScreen(id, ..) => Some(id), } }, MixedMessage::FromDevtools(_) => None, @@ -1731,6 +1736,7 @@ impl ScriptThread { msg @ ConstellationControlMsg::Viewport(..) | msg @ ConstellationControlMsg::SetScrollState(..) | msg @ ConstellationControlMsg::Resize(..) | + msg @ ConstellationControlMsg::ExitFullScreen(..) | msg @ ConstellationControlMsg::ExitScriptThread => { panic!("should have handled {:?} already", msg) }, @@ -1953,6 +1959,19 @@ impl ScriptThread { warn!("resize sent to nonexistent pipeline"); } + // exit_fullscreen creates a new JS promise object, so we need to have entered a compartment + fn handle_exit_fullscreen(&self, id: PipelineId) { + let document = self.documents.borrow().find_document(id); + if let Some(document) = document { + let _ac = JSAutoCompartment::new( + document.global().get_cx(), + document.reflector().get_jsobject().get(), + ); + document.exit_fullscreen(); + return; + } + } + fn handle_viewport(&self, id: PipelineId, rect: Rect) { let document = self.documents.borrow().find_document(id); if let Some(document) = document { diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 6c5f6500a5a..ea09d5a3f18 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -262,6 +262,8 @@ pub enum ConstellationControlMsg { Resize(PipelineId, WindowSizeData, WindowSizeType), /// Notifies script that window has been resized but to not take immediate action. ResizeInactive(PipelineId, WindowSizeData), + /// Window switched from fullscreen mode. + ExitFullScreen(PipelineId), /// Notifies the script that the document associated with this pipeline should 'unload'. UnloadDocument(PipelineId), /// Notifies the script that a pipeline should be closed. @@ -388,6 +390,7 @@ impl fmt::Debug for ConstellationControlMsg { Reload(..) => "Reload", WebVREvents(..) => "WebVREvents", PaintMetric(..) => "PaintMetric", + ExitFullScreen(..) => "ExitFullScreen", }; write!(formatter, "ConstellationControlMsg::{}", variant) } @@ -782,6 +785,8 @@ pub enum ConstellationMsg { EnableProfiler(Duration, Duration), /// Disable the sampling profiler. DisableProfiler, + /// Request to exit from fullscreen mode + ExitFullScreen(TopLevelBrowsingContextId), } impl fmt::Debug for ConstellationMsg { @@ -811,6 +816,7 @@ impl fmt::Debug for ConstellationMsg { SetCursor(..) => "SetCursor", EnableProfiler(..) => "EnableProfiler", DisableProfiler => "DisableProfiler", + ExitFullScreen(..) => "ExitFullScreen", }; write!(formatter, "ConstellationMsg::{}", variant) } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 2e3b7c8082b..5545d291afc 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -401,6 +401,13 @@ where self.compositor.maybe_start_shutting_down(); }, + WindowEvent::ExitFullScreen(top_level_browsing_context_id) => { + let msg = ConstellationMsg::ExitFullScreen(top_level_browsing_context_id); + if let Err(e) = self.constellation_chan.send(msg) { + warn!("Sending exit fullscreen to constellation failed ({:?}).", e); + } + }, + WindowEvent::Reload(top_level_browsing_context_id) => { let msg = ConstellationMsg::Reload(top_level_browsing_context_id); if let Err(e) = self.constellation_chan.send(msg) { diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index 52c2ed19662..6e74b462399 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -159,7 +159,15 @@ impl Browser { } }) .shortcut(Modifiers::empty(), Key::Escape, || { - self.event_queue.push(WindowEvent::Quit); + let state = self.window.get_fullscreen(); + if state { + if let Some(id) = self.browser_id { + let event = WindowEvent::ExitFullScreen(id); + self.event_queue.push(event); + } + } else { + self.event_queue.push(WindowEvent::Quit); + } }) .otherwise(|| self.platform_handle_key(key_event)); } diff --git a/ports/servo/glutin_app/window.rs b/ports/servo/glutin_app/window.rs index 6e24226cadb..8c4acf75f93 100644 --- a/ports/servo/glutin_app/window.rs +++ b/ports/servo/glutin_app/window.rs @@ -329,7 +329,7 @@ impl Window { match self.kind { WindowKind::Window(ref window, ..) => { if self.fullscreen.get() != state { - window.set_fullscreen(None); + window.set_fullscreen(Some(window.get_primary_monitor())); } }, WindowKind::Headless(..) => {}, @@ -337,6 +337,10 @@ impl Window { self.fullscreen.set(state); } + pub fn get_fullscreen(&self) -> bool { + return self.fullscreen.get(); + } + fn is_animating(&self) -> bool { self.animation_state.get() == AnimationState::Animating && !self.suspended.get() }