Changeset 196062 in webkit
- Timestamp:
- Feb 3, 2016 3:04:33 AM (8 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r196059 r196062 1 2016-02-03 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK] Reduce IPC traffic due to view state changes 4 https://bugs.webkit.org/show_bug.cgi?id=153745 5 6 Reviewed by Sergio Villar Senin. 7 8 Very often view state changes happen one after another in a very 9 short period of time, even in the same run loop iteration. For 10 example, when you switch to the web view window, the view is 11 focused and the active window flag changes as well. In that case 12 we are sending two messages to the web process and the page 13 updates its status according to the new flags in two steps. So, we 14 could group all state changes happening in the same run loop 15 iteration and notify about them all in the next iteration. This 16 also prevents unnecessary changes of state when we quickly go back 17 to a previous state, for example in focus follows mouse 18 configurations if you move the mouse outside the window and then 19 inside the window again quickly. 20 21 * UIProcess/API/gtk/WebKitWebViewBase.cpp: 22 (_WebKitWebViewBasePrivate::_WebKitWebViewBasePrivate): Use 23 VirewState::Flags to keep the web view state instead of 24 boolean, and also to keep the flags that need to be updated. Use a 25 timer to update web view state flags. 26 (_WebKitWebViewBasePrivate::updateViewStateTimerFired): Call 27 WebPageProxy::viewStateDidChange() and reset the flags that need 28 to be updated. 29 (webkitWebViewBaseScheduleUpdateViewState): Update the flags that 30 need to be updated and schedule the timer if it's not active. 31 (toplevelWindowFocusInEvent): Use the flags and schedule an update. 32 (toplevelWindowFocusOutEvent): Ditto. 33 (toplevelWindowStateEvent): Also mark the view as hidden when minimized. 34 (webkitWebViewBaseSetToplevelOnScreenWindow): Connect to 35 window-state-event instead of deprecated visibility-notify-event. 36 (webkitWebViewBaseMap): Use the flags and schedule an update. 37 (webkitWebViewBaseUnmap): Ditto. 38 (webkitWebViewBaseSetFocus): Ditto. 39 (webkitWebViewBaseIsInWindowActive): Use the flags. 40 (webkitWebViewBaseIsFocused): Ditto 41 (webkitWebViewBaseIsVisible): Ditto. 42 (webkitWebViewBaseIsInWindow): Removed this since it was unused. 43 * UIProcess/API/gtk/WebKitWebViewBasePrivate.h: 44 1 45 2016-02-03 Carlos Garcia Campos <cgarcia@igalia.com> 2 46 -
trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
r194846 r196062 149 149 150 150 struct _WebKitWebViewBasePrivate { 151 _WebKitWebViewBasePrivate() 152 : updateViewStateTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::updateViewStateTimerFired) 151 153 #if USE(REDIRECTED_XCOMPOSITE_WINDOW) 152 _WebKitWebViewBasePrivate()153 : clearRedirectedWindowSoonTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::clearRedirectedWindowSoonTimerFired) 154 , clearRedirectedWindowSoonTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::clearRedirectedWindowSoonTimerFired) 155 #endif 154 156 { 155 157 } 156 158 159 void updateViewStateTimerFired() 160 { 161 if (!pageProxy) 162 return; 163 pageProxy->viewStateDidChange(viewStateFlagsToUpdate); 164 viewStateFlagsToUpdate = ViewState::NoFlags; 165 } 166 167 #if USE(REDIRECTED_XCOMPOSITE_WINDOW) 157 168 void clearRedirectedWindowSoonTimerFired() 158 169 { … … 183 194 unsigned long toplevelFocusInEventID; 184 195 unsigned long toplevelFocusOutEventID; 185 unsigned long toplevel VisibilityEventID;196 unsigned long toplevelWindowStateEventID; 186 197 187 198 // View State. 188 bool isInWindowActive : 1; 189 bool isFocused : 1; 190 bool isVisible : 1; 191 bool isWindowVisible : 1; 199 ViewState::Flags viewState; 200 ViewState::Flags viewStateFlagsToUpdate; 201 RunLoop::Timer<WebKitWebViewBasePrivate> updateViewStateTimer; 192 202 193 203 WebKitWebViewBaseDownloadRequestHandler downloadHandler; … … 217 227 WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER) 218 228 229 static void webkitWebViewBaseScheduleUpdateViewState(WebKitWebViewBase* webViewBase, ViewState::Flags flagsToUpdate) 230 { 231 WebKitWebViewBasePrivate* priv = webViewBase->priv; 232 priv->viewStateFlagsToUpdate |= flagsToUpdate; 233 if (priv->updateViewStateTimer.isActive()) 234 return; 235 236 priv->updateViewStateTimer.startOneShot(0); 237 } 238 219 239 static gboolean toplevelWindowFocusInEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase) 220 240 { 221 241 WebKitWebViewBasePrivate* priv = webViewBase->priv; 222 if (!priv->isInWindowActive) { 223 priv->isInWindowActive = true; 224 priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive); 225 } 242 if (priv->viewState & ViewState::WindowIsActive) 243 return FALSE; 244 245 priv->viewState |= ViewState::WindowIsActive; 246 webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::WindowIsActive); 226 247 227 248 return FALSE; … … 231 252 { 232 253 WebKitWebViewBasePrivate* priv = webViewBase->priv; 233 if (priv->isInWindowActive) { 234 priv->isInWindowActive = false; 235 priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive); 236 } 254 if (!(priv->viewState & ViewState::WindowIsActive)) 255 return FALSE; 256 257 priv->viewState &= ~ViewState::WindowIsActive; 258 webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::WindowIsActive); 237 259 238 260 return FALSE; 239 261 } 240 262 241 static gboolean toplevelWindowVisibilityEvent(GtkWidget*, GdkEventVisibility* visibilityEvent, WebKitWebViewBase* webViewBase) 242 { 243 WebKitWebViewBasePrivate* priv = webViewBase->priv; 244 bool isWindowVisible = visibilityEvent->state != GDK_VISIBILITY_FULLY_OBSCURED; 245 if (priv->isWindowVisible != isWindowVisible) { 246 priv->isWindowVisible = isWindowVisible; 247 priv->pageProxy->viewStateDidChange(ViewState::IsVisible); 248 } 263 static gboolean toplevelWindowStateEvent(GtkWidget*, GdkEventWindowState* event, WebKitWebViewBase* webViewBase) 264 { 265 WebKitWebViewBasePrivate* priv = webViewBase->priv; 266 if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED)) 267 return FALSE; 268 269 bool visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED); 270 if ((visible && priv->viewState & ViewState::IsVisible) || (!visible && !(priv->viewState & ViewState::IsVisible))) 271 return FALSE; 272 273 if (visible) 274 priv->viewState |= ViewState::IsVisible; 275 else 276 priv->viewState &= ~ViewState::IsVisible; 277 webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible); 249 278 250 279 return FALSE; … … 265 294 priv->toplevelFocusOutEventID = 0; 266 295 } 267 if (priv->toplevel VisibilityEventID) {268 g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevel VisibilityEventID);269 priv->toplevel VisibilityEventID = 0;296 if (priv->toplevelWindowStateEventID) { 297 g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowStateEventID); 298 priv->toplevelWindowStateEventID = 0; 270 299 } 271 300 272 301 priv->toplevelOnScreenWindow = window; 273 priv->pageProxy->viewStateDidChange(ViewState::IsInWindow); 302 if (!(priv->viewState & ViewState::IsInWindow)) { 303 priv->viewState |= ViewState::IsInWindow; 304 webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsInWindow); 305 } 274 306 if (!priv->toplevelOnScreenWindow) 275 307 return; … … 281 313 g_signal_connect(priv->toplevelOnScreenWindow, "focus-out-event", 282 314 G_CALLBACK(toplevelWindowFocusOutEvent), webViewBase); 283 priv->toplevelVisibilityEventID = 284 g_signal_connect(priv->toplevelOnScreenWindow, "visibility-notify-event", 285 G_CALLBACK(toplevelWindowVisibilityEvent), webViewBase); 315 priv->toplevelWindowStateEventID = 316 g_signal_connect(priv->toplevelOnScreenWindow, "window-state-event", G_CALLBACK(toplevelWindowStateEvent), webViewBase); 286 317 } 287 318 … … 640 671 WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); 641 672 WebKitWebViewBasePrivate* priv = webViewBase->priv; 642 if (!priv->isVisible) { 643 priv->isVisible = true; 644 priv->pageProxy->viewStateDidChange(ViewState::IsVisible); 645 } 673 if (priv->viewState & ViewState::IsVisible) 674 return; 675 676 priv->viewState |= ViewState::IsVisible; 677 webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible); 646 678 } 647 679 … … 650 682 GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget); 651 683 652 WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; 653 if (priv->isVisible) { 654 priv->isVisible = false; 655 priv->pageProxy->viewStateDidChange(ViewState::IsVisible); 656 } 684 WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); 685 WebKitWebViewBasePrivate* priv = webViewBase->priv; 686 if (!(priv->viewState & ViewState::IsVisible)) 687 return; 688 689 priv->viewState &= ~ViewState::IsVisible; 690 webkitWebViewBaseScheduleUpdateViewState(webViewBase, ViewState::IsVisible); 657 691 } 658 692 … … 1301 1335 { 1302 1336 WebKitWebViewBasePrivate* priv = webViewBase->priv; 1303 if (priv->isFocused == focused) 1304 return; 1305 1306 unsigned viewStateFlags = ViewState::IsFocused; 1307 priv->isFocused = focused; 1308 1309 // If the view has received the focus and the window is not active 1310 // mark the current window as active now. This can happen if the 1311 // toplevel window is a GTK_WINDOW_POPUP and the focus has been 1312 // set programatically like WebKitTestRunner does, because POPUP 1313 // can't be focused. 1314 if (priv->isFocused && !priv->isInWindowActive) { 1315 priv->isInWindowActive = true; 1316 viewStateFlags |= ViewState::WindowIsActive; 1317 } 1318 priv->pageProxy->viewStateDidChange(viewStateFlags); 1337 if ((focused && priv->viewState & ViewState::IsFocused) || (!focused && !(priv->viewState & ViewState::IsFocused))) 1338 return; 1339 1340 ViewState::Flags flagsToUpdate = ViewState::IsFocused; 1341 if (focused) { 1342 priv->viewState |= ViewState::IsFocused; 1343 1344 // If the view has received the focus and the window is not active 1345 // mark the current window as active now. This can happen if the 1346 // toplevel window is a GTK_WINDOW_POPUP and the focus has been 1347 // set programatically like WebKitTestRunner does, because POPUP 1348 // can't be focused. 1349 if (!(priv->viewState & ViewState::WindowIsActive)) { 1350 priv->viewState |= ViewState::WindowIsActive; 1351 flagsToUpdate |= ViewState::WindowIsActive; 1352 } 1353 } else 1354 priv->viewState &= ~ViewState::IsFocused; 1355 1356 webkitWebViewBaseScheduleUpdateViewState(webViewBase, flagsToUpdate); 1319 1357 } 1320 1358 1321 1359 bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase) 1322 1360 { 1323 return webViewBase->priv-> isInWindowActive;1361 return webViewBase->priv->viewState & ViewState::WindowIsActive; 1324 1362 } 1325 1363 1326 1364 bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase) 1327 1365 { 1328 return webViewBase->priv-> isFocused;1366 return webViewBase->priv->viewState & ViewState::IsFocused; 1329 1367 } 1330 1368 1331 1369 bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase) 1332 1370 { 1333 return webViewBase->priv-> isVisible;1371 return webViewBase->priv->viewState & ViewState::IsVisible; 1334 1372 } 1335 1373 1336 1374 bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase) 1337 1375 { 1338 return webViewBase->priv->toplevelOnScreenWindow; 1339 } 1340 1341 bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase* webViewBase) 1342 { 1343 return webViewBase->priv->isWindowVisible; 1376 return webViewBase->priv->viewState & ViewState::IsInWindow; 1344 1377 } 1345 1378 -
trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
r191340 r196062 61 61 bool webkitWebViewBaseIsVisible(WebKitWebViewBase*); 62 62 bool webkitWebViewBaseIsInWindow(WebKitWebViewBase*); 63 bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase*);64 63 65 64 typedef void (*WebKitWebViewBaseDownloadRequestHandler) (WebKitWebViewBase*, WebKit::DownloadProxy*);
Note: See TracChangeset
for help on using the changeset viewer.