forked from mirrors/gecko-dev
		
	Bug 1563349 - Part 4 - Support NSPopoverTouchBarItem. r=spohl
Differential Revision: https://phabricator.services.mozilla.com/D47621 --HG-- extra : moz-landing-system : lando
This commit is contained in:
		
							parent
							
								
									dc2a166e28
								
							
						
					
					
						commit
						525bd39f48
					
				
					 9 changed files with 205 additions and 20 deletions
				
			
		|  | @ -74,6 +74,7 @@ def Libxul(name, output_category=None): | |||
|         LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSSharingServicePickerTouchBarItem'] | ||||
|         LDFLAGS += ['-Wl,-U,_OBJC_METACLASS_$_NSTouchBar'] | ||||
|         LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSCustomTouchBarItem'] | ||||
|         LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSPopoverTouchBarItem'] | ||||
|         LDFLAGS += ['-lresolv'] | ||||
| 
 | ||||
|     if CONFIG['MOZ_DEBUG_SYMBOLS'] and CONFIG['CC_TYPE'] == 'clang-cl': | ||||
|  |  | |||
|  | @ -130,18 +130,37 @@ using namespace mozilla::dom; | |||
| /**
 | ||||
|  * Updates an input on the Touch Bar by redirecting to one of the specific | ||||
|  * TouchBarItem types updaters. | ||||
|  * Returns true if the input was successfully updated. | ||||
|  */ | ||||
| - (void)updateItem:(TouchBarInput*)aInput; | ||||
| - (bool)updateItem:(TouchBarInput*)aInput; | ||||
| 
 | ||||
| /**
 | ||||
|  * Helper function for updateItem. Checks to see if a given input exists within | ||||
|  * any of this Touch Bar's popovers and updates it if it exists. | ||||
|  */ | ||||
| - (bool)maybeUpdatePopoverChild:(TouchBarInput*)aInput; | ||||
| 
 | ||||
| /**
 | ||||
|  * Helper function for updateItem. Replaces an item in the | ||||
|  * self.mappedLayoutItems dictionary. | ||||
|  */ | ||||
| - (void)replaceMappedLayoutItem:(TouchBarInput*)aItem; | ||||
| 
 | ||||
| /**
 | ||||
|  * Update or create various subclasses of TouchBarItem. | ||||
|  */ | ||||
| - (void)updateButton:(NSButton*)aButton input:(TouchBarInput*)aInput; | ||||
| - (void)updateMainButton:(NSButton*)aMainButton input:(TouchBarInput*)aInput; | ||||
| - (void)updatePopover:(NSPopoverTouchBarItem*)aPopoverItem input:(TouchBarInput*)aInput; | ||||
| - (NSTouchBarItem*)makeShareScrubberForIdentifier:(NSTouchBarItemIdentifier)aIdentifier; | ||||
| 
 | ||||
| /**
 | ||||
|  *  Redirects button actions to the appropriate handler and handles telemetry. | ||||
|  * If aShowing is true, aPopover is shown. Otherwise, it is hidden. | ||||
|  */ | ||||
| - (void)showPopover:(TouchBarInput*)aPopover showing:(bool)aShowing; | ||||
| 
 | ||||
| /**
 | ||||
|  *  Redirects button actions to the appropriate handler. | ||||
|  */ | ||||
| - (void)touchBarAction:(id)aSender; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|   @"button", | ||||
|   @"mainButton", | ||||
|   @"scrubber", | ||||
|   @"popover", | ||||
| ]; | ||||
| 
 | ||||
| // The system default width for Touch Bar inputs is 128px. This is double. | ||||
|  | @ -106,6 +107,15 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
| - (void)dealloc { | ||||
|   for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) { | ||||
|     NSTouchBarItem* item = [self itemForIdentifier:identifier]; | ||||
|     if (!item) { | ||||
|       continue; | ||||
|     } | ||||
|     if ([item isKindOfClass:[NSPopoverTouchBarItem class]]) { | ||||
|       [(NSPopoverTouchBarItem*)item setCollapsedRepresentation:nil]; | ||||
|       [(NSPopoverTouchBarItem*)item setCollapsedRepresentationImage:nil]; | ||||
|       [(nsTouchBar*)[(NSPopoverTouchBarItem*)item popoverTouchBar] release]; | ||||
|     } | ||||
| 
 | ||||
|     [item release]; | ||||
|   } | ||||
| 
 | ||||
|  | @ -139,6 +149,17 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|     return [self makeShareScrubberForIdentifier:aIdentifier]; | ||||
|   } | ||||
| 
 | ||||
|   if ([[input type] hasSuffix:@"popover"]) { | ||||
|     NSPopoverTouchBarItem* newPopoverItem = | ||||
|         [[NSPopoverTouchBarItem alloc] initWithIdentifier:aIdentifier]; | ||||
|     // We initialize popoverTouchBar here because we only allow setting this | ||||
|     // property on popover creation. Updating popoverTouchBar for every update | ||||
|     // of the popover item would be very expensive. | ||||
|     newPopoverItem.popoverTouchBar = [[nsTouchBar alloc] initWithInputs:[input children]]; | ||||
|     [self updatePopover:newPopoverItem input:input]; | ||||
|     return newPopoverItem; | ||||
|   } | ||||
| 
 | ||||
|   // Our new item, which will be initialized depending on aIdentifier. | ||||
|   NSCustomTouchBarItem* newItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:aIdentifier]; | ||||
| 
 | ||||
|  | @ -154,10 +175,14 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|   return newItem; | ||||
| } | ||||
| 
 | ||||
| - (void)updateItem:(TouchBarInput*)aInput { | ||||
| - (bool)updateItem:(TouchBarInput*)aInput { | ||||
|   NSTouchBarItem* item = [self itemForIdentifier:[aInput nativeIdentifier]]; | ||||
|   if (!item) { | ||||
|     return; | ||||
|     if ([self maybeUpdatePopoverChild:aInput]) { | ||||
|       [self replaceMappedLayoutItem:aInput]; | ||||
|       return true; | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   if ([[aInput type] hasSuffix:@"button"]) { | ||||
|  | @ -166,10 +191,34 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|   } else if ([[aInput type] hasSuffix:@"mainButton"]) { | ||||
|     [(NSCustomTouchBarItem*)item setCustomizationLabel:[aInput title]]; | ||||
|     [self updateMainButton:(NSButton*)item.view input:aInput]; | ||||
|   } else if ([[aInput type] hasSuffix:@"popover"]) { | ||||
|     [(NSPopoverTouchBarItem*)item setCustomizationLabel:[aInput title]]; | ||||
|     [self updatePopover:(NSPopoverTouchBarItem*)item input:aInput]; | ||||
|   } | ||||
| 
 | ||||
|   [self.mappedLayoutItems[[aInput nativeIdentifier]] release]; | ||||
|   self.mappedLayoutItems[[aInput nativeIdentifier]] = aInput; | ||||
|   [self replaceMappedLayoutItem:aInput]; | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| - (bool)maybeUpdatePopoverChild:(TouchBarInput*)aInput { | ||||
|   for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) { | ||||
|     TouchBarInput* potentialPopover = self.mappedLayoutItems[identifier]; | ||||
|     if (![[potentialPopover type] hasSuffix:@"popover"]) { | ||||
|       continue; | ||||
|     } | ||||
|     NSTouchBarItem* popover = [self itemForIdentifier:[potentialPopover nativeIdentifier]]; | ||||
|     if (popover) { | ||||
|       if ([(nsTouchBar*)[(NSPopoverTouchBarItem*)popover popoverTouchBar] updateItem:aInput]) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| - (void)replaceMappedLayoutItem:(TouchBarInput*)aItem { | ||||
|   [self.mappedLayoutItems[[aItem nativeIdentifier]] release]; | ||||
|   self.mappedLayoutItems[[aItem nativeIdentifier]] = aItem; | ||||
| } | ||||
| 
 | ||||
| - (void)updateButton:(NSButton*)aButton input:(TouchBarInput*)aInput { | ||||
|  | @ -220,6 +269,25 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|                           forOrientation:NSLayoutConstraintOrientationHorizontal]; | ||||
| } | ||||
| 
 | ||||
| - (void)updatePopover:(NSPopoverTouchBarItem*)aPopoverItem input:(TouchBarInput*)aInput { | ||||
|   if (!aPopoverItem || !aInput) { | ||||
|     return; | ||||
|   } | ||||
|   aPopoverItem.showsCloseButton = YES; | ||||
|   if ([aInput imageURI]) { | ||||
|     RefPtr<nsTouchBarInputIcon> icon = [aInput icon]; | ||||
|     if (!icon) { | ||||
|       icon = new nsTouchBarInputIcon([aInput document], nil, nil, aPopoverItem); | ||||
|       [aInput setIcon:icon]; | ||||
|     } | ||||
|     icon->SetupIcon([aInput imageURI]); | ||||
|   } else if ([aInput title]) { | ||||
|     aPopoverItem.collapsedRepresentationLabel = [aInput title]; | ||||
|   } else { | ||||
|     aPopoverItem.collapsedRepresentation = nil; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| - (NSTouchBarItem*)makeShareScrubberForIdentifier:(NSTouchBarItemIdentifier)aIdentifier { | ||||
|   TouchBarInput* input = self.mappedLayoutItems[aIdentifier]; | ||||
|   // System-default share menu | ||||
|  | @ -242,6 +310,22 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|   return servicesItem; | ||||
| } | ||||
| 
 | ||||
| - (void)showPopover:(TouchBarInput*)aPopover showing:(bool)aShowing { | ||||
|   if (!aPopover) { | ||||
|     return; | ||||
|   } | ||||
|   NSPopoverTouchBarItem* popoverItem = | ||||
|       (NSPopoverTouchBarItem*)[self itemForIdentifier:[aPopover nativeIdentifier]]; | ||||
|   if (!popoverItem) { | ||||
|     return; | ||||
|   } | ||||
|   if (aShowing) { | ||||
|     [popoverItem showPopover:self]; | ||||
|   } else { | ||||
|     [popoverItem dismissPopover:self]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| - (void)touchBarAction:(id)aSender { | ||||
|   NSTouchBarItemIdentifier identifier = | ||||
|       objc_getAssociatedObject(aSender, &sIdentifierAssociationKey); | ||||
|  | @ -271,6 +355,12 @@ static const NSArray<NSString*>* kAllowedInputTypes = @[ | |||
|     if (!input) { | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     if ([[input type] hasSuffix:@"popover"]) { | ||||
|       NSTouchBarItem* item = [self itemForIdentifier:identifier]; | ||||
|       [(nsTouchBar*)[(NSPopoverTouchBarItem*)item popoverTouchBar] releaseJSObjects]; | ||||
|     } | ||||
| 
 | ||||
|     [input setCallback:nil]; | ||||
|     [input setDocument:nil]; | ||||
|     [input setImageURI:nil]; | ||||
|  |  | |||
|  | @ -26,9 +26,9 @@ class imgRequestProxy; | |||
| class nsTouchBarInputIcon : public nsIconLoaderObserver { | ||||
|  public: | ||||
|   explicit nsTouchBarInputIcon( | ||||
|       RefPtr<Document> aDocument, | ||||
|       NSButton* aButton, | ||||
|       NSSharingServicePickerTouchBarItem* aShareScrubber = nil); | ||||
|       RefPtr<Document> aDocument, NSButton* aButton, | ||||
|       NSSharingServicePickerTouchBarItem* aShareScrubber = nil, | ||||
|       NSPopoverTouchBarItem* aPopoverItem = nil); | ||||
| 
 | ||||
|  private: | ||||
|   virtual ~nsTouchBarInputIcon(); | ||||
|  | @ -59,6 +59,8 @@ class nsTouchBarInputIcon : public nsIconLoaderObserver { | |||
|   // NSSharingServicePickerTouchBarItem does not expose an NSButton* on which we
 | ||||
|   // can set the `image` property.
 | ||||
|   NSSharingServicePickerTouchBarItem* mShareScrubber; | ||||
|   // We accept a popover only as a special case.
 | ||||
|   NSPopoverTouchBarItem* mPopoverItem; | ||||
|   // The icon loader object should never outlive its creating
 | ||||
|   // nsTouchBarInputIcon object.
 | ||||
|   RefPtr<nsIconLoaderService> mIconLoader; | ||||
|  |  | |||
|  | @ -22,10 +22,14 @@ using namespace mozilla; | |||
| static const uint32_t kIconSize = 16; | ||||
| static const CGFloat kHiDPIScalingFactor = 2.0f; | ||||
| 
 | ||||
| nsTouchBarInputIcon::nsTouchBarInputIcon(RefPtr<Document> aDocument, | ||||
|                                          NSButton* aButton, | ||||
|                                          NSSharingServicePickerTouchBarItem* aShareScrubber) | ||||
|     : mDocument(aDocument), mSetIcon(false), mButton(aButton), mShareScrubber(aShareScrubber) { | ||||
| nsTouchBarInputIcon::nsTouchBarInputIcon(RefPtr<Document> aDocument, NSButton* aButton, | ||||
|                                          NSSharingServicePickerTouchBarItem* aShareScrubber, | ||||
|                                          NSPopoverTouchBarItem* aPopoverItem) | ||||
|     : mDocument(aDocument), | ||||
|       mSetIcon(false), | ||||
|       mButton(aButton), | ||||
|       mShareScrubber(aShareScrubber), | ||||
|       mPopoverItem(aPopoverItem) { | ||||
|   MOZ_COUNT_CTOR(nsTouchBarInputIcon); | ||||
| } | ||||
| 
 | ||||
|  | @ -45,13 +49,14 @@ void nsTouchBarInputIcon::Destroy() { | |||
| 
 | ||||
|   mButton = nil; | ||||
|   mShareScrubber = nil; | ||||
|   mPopoverItem = nil; | ||||
| } | ||||
| 
 | ||||
| nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) { | ||||
|   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; | ||||
| 
 | ||||
|   // Still don't have one, then something is wrong, get out of here. | ||||
|   if (!(mButton || mShareScrubber)) { | ||||
|   if (!(mButton || mShareScrubber || mPopoverItem)) { | ||||
|     NS_ERROR("No Touch Bar button"); | ||||
|     return NS_ERROR_FAILURE; | ||||
|   } | ||||
|  | @ -70,6 +75,7 @@ nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) { | |||
|     // Load placeholder icon. | ||||
|     [mButton setImage:mIconLoader->GetNativeIconImage()]; | ||||
|     [mShareScrubber setButtonImage:mIconLoader->GetNativeIconImage()]; | ||||
|     [mPopoverItem setCollapsedRepresentationImage:mIconLoader->GetNativeIconImage()]; | ||||
|   } | ||||
| 
 | ||||
|   nsresult rv = mIconLoader->LoadIcon(aIconURI); | ||||
|  | @ -79,6 +85,7 @@ nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) { | |||
|     // been set.  Clear it. | ||||
|     [mButton setImage:nil]; | ||||
|     [mShareScrubber setButtonImage:nil]; | ||||
|     [mPopoverItem setCollapsedRepresentationImage:nil]; | ||||
|   } | ||||
| 
 | ||||
|   mSetIcon = true; | ||||
|  | @ -95,6 +102,7 @@ nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) { | |||
| nsresult nsTouchBarInputIcon::OnComplete(NSImage* aImage) { | ||||
|   [mButton setImage:aImage]; | ||||
|   [mShareScrubber setButtonImage:aImage]; | ||||
|   [mPopoverItem setCollapsedRepresentationImage:aImage]; | ||||
| 
 | ||||
|   [aImage release]; | ||||
|   return NS_OK; | ||||
|  |  | |||
|  | @ -58,6 +58,17 @@ __attribute__((weak_import)) @interface NSTouchBar : NSObject | |||
| - (NSTouchBarItem*)itemForIdentifier:(NSTouchBarItemIdentifier)aIdentifier; | ||||
| @end | ||||
| 
 | ||||
| __attribute__((weak_import)) @interface NSPopoverTouchBarItem : NSTouchBarItem | ||||
| @property(strong) NSString* customizationLabel; | ||||
| @property(strong) NSView* collapsedRepresentation; | ||||
| @property(strong) NSImage* collapsedRepresentationImage; | ||||
| @property(strong) NSString* collapsedRepresentationLabel; | ||||
| @property(strong) NSTouchBar* popoverTouchBar; | ||||
| @property BOOL showsCloseButton; | ||||
| - (void)showPopover:(id)sender; | ||||
| - (void)dismissPopover:(id)sender; | ||||
| @end | ||||
| 
 | ||||
| @interface NSButton (TouchBarButton) | ||||
| @property(strong) NSColor* bezelColor; | ||||
| @end | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #define nsTouchBarUpdater_h_ | ||||
| 
 | ||||
| #include "nsITouchBarUpdater.h" | ||||
| #include "nsCocoaWindow.h" | ||||
| 
 | ||||
| class nsTouchBarUpdater : public nsITouchBarUpdater { | ||||
|  public: | ||||
|  | @ -16,6 +17,7 @@ class nsTouchBarUpdater : public nsITouchBarUpdater { | |||
| 
 | ||||
|  protected: | ||||
|   virtual ~nsTouchBarUpdater() {} | ||||
|   BaseWindow* GetCocoaWindow(nsIBaseWindow* aWindow); | ||||
| }; | ||||
| 
 | ||||
| #endif  // nsTouchBarUpdater_h_
 | ||||
|  |  | |||
|  | @ -9,7 +9,6 @@ | |||
| #include "nsTouchBarUpdater.h" | ||||
| #include "nsTouchBarNativeAPIDefines.h" | ||||
| 
 | ||||
| #include "nsCocoaWindow.h" | ||||
| #include "nsIArray.h" | ||||
| #include "nsIBaseWindow.h" | ||||
| #include "nsIWidget.h" | ||||
|  | @ -28,12 +27,11 @@ NS_IMPL_ISUPPORTS(nsTouchBarUpdater, nsITouchBarUpdater); | |||
| NS_IMETHODIMP | ||||
| nsTouchBarUpdater::UpdateTouchBarInputs(nsIBaseWindow* aWindow, | ||||
|                                         const nsTArray<RefPtr<nsITouchBarInput>>& aInputs) { | ||||
|   nsCOMPtr<nsIWidget> widget = nullptr; | ||||
|   aWindow->GetMainWidget(getter_AddRefs(widget)); | ||||
|   if (!widget) { | ||||
|     return NS_ERROR_FAILURE; | ||||
|   if (!sTouchBarIsInitialized) { | ||||
|     return NS_OK; | ||||
|   } | ||||
|   BaseWindow* cocoaWin = (BaseWindow*)widget->GetNativeData(NS_NATIVE_WINDOW); | ||||
| 
 | ||||
|   BaseWindow* cocoaWin = nsTouchBarUpdater::GetCocoaWindow(aWindow); | ||||
|   if (!cocoaWin) { | ||||
|     return NS_ERROR_FAILURE; | ||||
|   } | ||||
|  | @ -54,6 +52,42 @@ nsTouchBarUpdater::UpdateTouchBarInputs(nsIBaseWindow* aWindow, | |||
|   return NS_OK; | ||||
| } | ||||
| 
 | ||||
| NS_IMETHODIMP | ||||
| nsTouchBarUpdater::ShowPopover(nsIBaseWindow* aWindow, nsITouchBarInput* aPopover, bool aShowing) { | ||||
|   if (!sTouchBarIsInitialized || !aPopover) { | ||||
|     return NS_OK; | ||||
|   } | ||||
| 
 | ||||
|   BaseWindow* cocoaWin = nsTouchBarUpdater::GetCocoaWindow(aWindow); | ||||
|   if (!cocoaWin) { | ||||
|     return NS_ERROR_FAILURE; | ||||
|   } | ||||
| 
 | ||||
|   if ([cocoaWin respondsToSelector:@selector(touchBar)]) { | ||||
|     // We don't need to completely reinitialize the popover. We only need its | ||||
|     // identifier to look it up in [nsTouchBar mappedLayoutItems]. | ||||
|     nsAutoString keyStr; | ||||
|     nsresult rv = aPopover->GetKey(keyStr); | ||||
|     if (NS_FAILED(rv)) { | ||||
|       return NS_ERROR_FAILURE; | ||||
|     } | ||||
|     NSString* key = nsCocoaUtils::ToNSString(keyStr); | ||||
| 
 | ||||
|     nsAutoString typeStr; | ||||
|     rv = aPopover->GetType(typeStr); | ||||
|     if (NS_FAILED(rv)) { | ||||
|       return NS_ERROR_FAILURE; | ||||
|     } | ||||
|     NSString* type = nsCocoaUtils::ToNSString(typeStr); | ||||
| 
 | ||||
|     TouchBarInput* popoverItem = [[(nsTouchBar*)cocoaWin.touchBar mappedLayoutItems] | ||||
|         objectForKey:[TouchBarInput nativeIdentifierWithType:type withKey:key]]; | ||||
| 
 | ||||
|     [(nsTouchBar*)cocoaWin.touchBar showPopover:popoverItem showing:aShowing]; | ||||
|   } | ||||
|   return NS_OK; | ||||
| } | ||||
| 
 | ||||
| NS_IMETHODIMP | ||||
| nsTouchBarUpdater::EnterCustomizeMode() { | ||||
|   [NSApp toggleTouchBarCustomizationPalette:(id)this]; | ||||
|  | @ -66,6 +100,19 @@ nsTouchBarUpdater::IsTouchBarInitialized(bool* aResult) { | |||
|   return NS_OK; | ||||
| } | ||||
| 
 | ||||
| BaseWindow* nsTouchBarUpdater::GetCocoaWindow(nsIBaseWindow* aWindow) { | ||||
|   nsCOMPtr<nsIWidget> widget = nullptr; | ||||
|   aWindow->GetMainWidget(getter_AddRefs(widget)); | ||||
|   if (!widget) { | ||||
|     return nil; | ||||
|   } | ||||
|   BaseWindow* cocoaWin = (BaseWindow*)widget->GetNativeData(NS_NATIVE_WINDOW); | ||||
|   if (!cocoaWin) { | ||||
|     return nil; | ||||
|   } | ||||
|   return cocoaWin; | ||||
| } | ||||
| 
 | ||||
| // NOTE: This method is for internal unit tests only. | ||||
| NS_IMETHODIMP | ||||
| nsTouchBarUpdater::SetTouchBarInitialized(bool aIsInitialized) { | ||||
|  |  | |||
|  | @ -34,4 +34,9 @@ interface nsITouchBarUpdater : nsISupports | |||
|    * sets this value after a Touch Bar is initialized on compatible Macs. | ||||
|    */ | ||||
|   void setTouchBarInitialized(in boolean aIsInitialized); | ||||
| 
 | ||||
|   /** | ||||
|    * If aShowing is true, aPopover is shown. Otherwise, it is hidden. | ||||
|    */ | ||||
|   void showPopover(in nsIBaseWindow aWindow, in nsITouchBarInput aPopover, in boolean aShowing); | ||||
| }; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 harry
						harry