OSStatus MakeWindowTransparent(WindowRef aWindowRef) { OSStatus status = paramErr; require(aWindowRef != NULL, paramErr); // is the window compositing or not? WindowAttributes attributes; status = GetWindowAttributes(aWindowRef, &attributes); require_noerr(status, GetWindowAttributes); /* if (attributes & kWindowCompositingAttribute) { // it is compositing so we intercept the kEventWindowGetRegion event to be able to specify an empty opaque region EventTypeSpec wCompositingEvents = { kEventClassWindow, kEventWindowGetRegion }; status = InstallWindowEventHandler(aWindowRef, TransparentWindowHandler, 1, &wCompositingEvents, aWindowRef, NULL); require_noerr(status, InstallWindowEventHandler); HIViewRef contentView; status = HIViewFindByID(HIViewGetRoot(aWindowRef), kHIViewWindowContentID, &contentView); require_noerr(status, HIViewFindByID); // and we intercept the kEventControlDraw event of our content view so that we can make it transparent EventTypeSpec cCompositingEvents = { kEventClassControl, kEventControlDraw }; status = InstallControlEventHandler(contentView, TransparentWindowHandler, 1, &cCompositingEvents, contentView, NULL); require_noerr(status, InstallControlEventHandler); } else*/ { // it is non-compositing so we intercept the kEventWindowGetRegion event to be able to specify an empty opaque region // and we intercept the kEventWindowDrawContent event of our window so that we can make it transparent EventTypeSpec wNonCompositingEvents[] = { { kEventClassWindow, kEventWindowGetRegion }, { kEventClassWindow, kEventWindowDrawContent } }; status = InstallWindowEventHandler(aWindowRef, TransparentWindowHandler, GetEventTypeCount(wNonCompositingEvents), wNonCompositingEvents, aWindowRef, NULL); require_noerr(status, InstallWindowEventHandler); } // telling the HIToolbox that our window is not opaque so that we will be asked for the opaque region UInt32 features; status = GetWindowFeatures(aWindowRef, &features); require_noerr(status, GetWindowFeatures); if ( ( features & kWindowIsOpaque ) != 0 ) { status = HIWindowChangeFeatures(aWindowRef, 0, kWindowIsOpaque); require_noerr(status, HIWindowChangeFeatures); } // force opaque shape to be recalculated status = ReshapeCustomWindow(aWindowRef); require_noerr(status, ReshapeCustomWindow); // ensure that HIToolbox doesn't use standard shadow style, which defeats custom opaque shape status = SetWindowAlpha(aWindowRef, 0.999); require_noerr(status, SetWindowAlpha); SetWindowAlpha: ReshapeCustomWindow: HIWindowChangeFeatures: GetWindowFeatures: InstallControlEventHandler: HIViewFindByID: InstallWindowEventHandler: GetWindowAttributes: paramErr: return status; }
/* Handle events of kEventClassControl that get sent to the Frame */ OSStatus HandleStarFrameControlEvents( EventHandlerCallRef inCallRef, EventRef inEvent, StarFrameData* frameData) { OSStatus retVal = eventNotHandledErr; switch(GetEventKind(inEvent)) { case kEventControlInitialize : retVal = HandleStarFrameInitialize(inCallRef, inEvent, frameData); break; case kEventControlOwningWindowChanged : { // We only want the star-shaped opaque area of our frame view to // draw. Everything else should be transparent. To accomplish that // we change the features of the owning window so that only the // content we draw shows up on screen WindowRef newWindow = GetControlOwner(frameData->hiSelf); HIWindowChangeFeatures(newWindow, 0, kWindowIsOpaque); } break; case kEventControlBoundsChanged : { retVal = HandleStarFrameBoundsChanged(inCallRef, inEvent, frameData); } break; case kEventControlDraw : { HIRect bounds; CGContextRef cgContext; HIViewGetBounds(frameData->hiSelf, &bounds); float radius = fmin(CGRectGetWidth(bounds) / 2.0, CGRectGetHeight(bounds) / 2.0); GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(cgContext), NULL, &cgContext ); if(NULL != cgContext) { HIThemeMenuDrawInfo drawInfo; CGPathRef starPath = CreatePathForStarFrame(frameData, radius); drawInfo.version = 0; drawInfo.menuType = frameData->menuType; // HIThemeDrawMenuBackground is designed to draw the pin striped background // of standard menus. Our menu is a star and so HIThemeDrawMenuBackground may not be // appropriate in this case. Nevertheless, we'll draw the standard menu background for // this menu and clip it to a star. CGContextClearRect(cgContext, bounds); CGContextSaveGState(cgContext); CGContextTranslateCTM(cgContext, radius, radius); CGContextAddPath(cgContext, starPath); CGContextClip(cgContext); CGContextTranslateCTM(cgContext, -radius, -radius); HIThemeDrawMenuBackground(&bounds, &drawInfo, cgContext, kHIThemeOrientationNormal); CGContextRestoreGState(cgContext); // The pin striping looks a bit odd sort of floating out by itself. We'll also add // a lovely gray line to help emphasize the boundary CGContextTranslateCTM(cgContext, radius, radius); CGContextAddPath(cgContext, starPath); CGContextSetRGBStrokeColor(cgContext, 0.8, 0.8, 0.8, 1.0); CGContextSetLineWidth(cgContext, 1.0); CGContextStrokePath(cgContext); CGPathRelease(starPath); starPath = NULL; } retVal = noErr; } break; // Mac OS X v10.4 introduced a Window Manager bug. // The workaround is to implement the kEventControlGetFrameMetrics handler. // Even after the bug is fixed, the workaround will not be harmful. case kEventControlGetFrameMetrics: { HIViewRef contentView = NULL; // If we can find our content view, ask it for our metrics verify_noerr(HIViewFindByID(frameData->hiSelf, kHIViewWindowContentID, &contentView)); if(NULL != contentView) { retVal = SendEventToEventTargetWithOptions( inEvent, GetControlEventTarget( contentView ), kEventTargetDontPropagate ); } } break; default: break; } return retVal; }
void MCStack::realize() { //create window if (!MCnoui && MCModeMakeLocalWindows()) { if ( getextendedstate(ECS_FULLSCREEN) ) { //TS-2008-08-01 : [[Bug 5703 - fullscreen stack prop interacts badly with HideMenuBar]] if (!((MCScreenDC*)MCscreen)->getmenubarhidden()) SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); const MCDisplay *t_display; t_display = MCscreen -> getnearestdisplay(rect); MCRectangle t_workarea, t_viewport; t_workarea = t_display -> workarea; t_viewport = t_display -> viewport ; setrect(t_viewport); } else { if (!((MCScreenDC*)MCscreen)->getmenubarhidden()) SetSystemUIMode(kUIModeNormal, NULL); } Rect wrect; MCScreenDC *psdc = (MCScreenDC *)MCscreen; psdc->MCRect2MacRect(rect, wrect); window = new _Drawable; window->type = DC_WINDOW; window->handle.window = 0; char *tmpname = NULL; const unsigned char *namePascal; if (!isunnamed()) { //set window title to name of stack temporarily. tmpname = strclone(getname_cstring()); //it will be changed by setname() later. namePascal = c2pstr(tmpname); } else namePascal = (unsigned char*)"\p"; loadwindowshape(); window->handle.window = NULL; uint32_t wclass; uint32_t wattributes; getWinstyle(wattributes,wclass); wattributes |= kWindowCompositingAttribute; long testdecorations = WD_TITLE | WD_MENU | WD_CLOSE | WD_MINIMIZE | WD_MAXIMIZE; if (m_window_shape != NULL) { static WindowDefUPP s_window_mask_proc = NULL; if (s_window_mask_proc == NULL) s_window_mask_proc = NewWindowDefUPP(WindowMaskProc); WindowDefSpec t_spec; t_spec . defType = kWindowDefProcPtr; t_spec . u . defProc = s_window_mask_proc; CreateCustomWindow(&t_spec, wclass, wattributes, &wrect, (WindowPtr *)&window -> handle . window); HIWindowChangeFeatures((WindowPtr)window -> handle . window, 0, kWindowIsOpaque); } else if (((flags & F_DECORATIONS && !(decorations & testdecorations)) || wclass == kPlainWindowClass)) { static WindowDefUPP s_borderless_proc = NULL; if (s_borderless_proc == NULL) s_borderless_proc = NewWindowDefUPP(BorderlessWindowProc); WindowDefSpec t_spec; t_spec . defType = kWindowDefProcPtr; t_spec . u . defProc = s_borderless_proc; if (wclass == kPlainWindowClass) wclass = kUtilityWindowClass; CreateCustomWindow(&t_spec, wclass, wattributes, &wrect, (WindowPtr *)&window->handle.window); } else CreateNewWindow(wclass, wattributes,&wrect, (WindowPtr *)&window->handle.window); if (wclass == kFloatingWindowClass) ChangeWindowAttributes((WindowPtr)window -> handle . window, kWindowNoAttributes, kWindowHideOnSuspendAttribute); // MW-2009-10-31: Make sure we can collapse any rev window HIWindowChangeFeatures((WindowPtr)window -> handle . window, kWindowCanCollapse, 0); if (window->handle.window == NULL) SetWTitle((WindowPtr)window->handle.window, namePascal); SetWTitle((WindowPtr)window->handle.window, namePascal); setopacity(blendlevel * 255 / 100); SetWRefCon((WindowPtr)window->handle.window, mode); ControlRef t_control; MCRevolutionStackViewCreate(this, &t_control); ControlRef t_root_control; GetRootControl((WindowPtr)window -> handle . window, &t_root_control); HIViewAddSubview(t_root_control, t_control); ShowControl(t_control); if (wclass == kDrawerWindowClass) { Window pwindow = NULL; if (parentwindow != DNULL) pwindow = parentwindow; else if (MCdefaultstackptr && MCdefaultstackptr->getw() != DNULL ) pwindow = MCdefaultstackptr->getw(); if (pwindow && GetWRefCon((WindowPtr)pwindow->handle.window) != WM_DRAWER) { SetDrawerParent((WindowPtr)window->handle.window, (WindowPtr)pwindow->handle.window); WindowAttributes watt; GetWindowAttributes((WindowPtr)pwindow->handle.window,&watt); if (wattributes & kWindowResizableAttribute) ChangeWindowAttributes((WindowPtr)pwindow->handle.window, kWindowLiveResizeAttribute, 0); OptionBits draweredge; switch (wposition) { case WP_PARENTTOP: draweredge = kWindowEdgeTop; break; case WP_PARENTRIGHT: draweredge = kWindowEdgeRight; break; case WP_PARENTBOTTOM: draweredge = kWindowEdgeBottom; break; case WP_PARENTLEFT: draweredge = kWindowEdgeLeft; break; default: draweredge = kWindowEdgeDefault; break; } SetDrawerPreferredEdge((WindowPtr)window->handle.window, draweredge); if (walignment) { MCRectangle parentwindowrect; MCscreen->getwindowgeometry(pwindow, parentwindowrect); int2 wspace = 0; RgnHandle r = NewRgn(); GetWindowRegion((WindowPtr)window->handle.window, kWindowStructureRgn, r); Rect tRect; GetRegionBounds(r, &tRect); DisposeRgn(r); MCRectangle drawerwindowrect; psdc->MacRect2MCRect(tRect, drawerwindowrect); if (wposition == WP_PARENTTOP || wposition == WP_PARENTBOTTOM) { wspace = parentwindowrect.width - drawerwindowrect.width; if (watt & kWindowMetalAttribute) if (wspace) wspace += 10; //for metal } else { wspace = parentwindowrect.height - drawerwindowrect.height; if (watt & kWindowMetalAttribute) if (wspace) wspace += 5; //for metal } if (wspace > 0) switch (walignment) { case OP_CENTER: SetDrawerOffsets ((WindowPtr)window->handle.window,ceil(wspace/2) -1,floor(wspace/2) + 1); break; case OP_RIGHT: case OP_BOTTOM: SetDrawerOffsets ((WindowPtr)window->handle.window,wspace,0); break; case OP_TOP: case OP_LEFT: SetDrawerOffsets ((WindowPtr)window->handle.window,0,wspace); break; } } } } delete tmpname; // MW-2005-11-06: We also need to catch window constraining events so we can flush // the screen geometry cache. EventTypeSpec list[] = { {kEventClassWindow, kEventWindowCollapsed}, {kEventClassWindow, kEventWindowExpanded}, {kEventClassMouse, kEventMouseWheelMoved}, {kEventClassWindow, kEventWindowBoundsChanging}, {kEventClassWindow, kEventWindowBoundsChanged}, {kEventClassWindow, kEventWindowConstrain}, {kEventClassWindow, kEventWindowFocusAcquired}, {kEventClassWindow, kEventWindowFocusRelinquish}, {kEventClassWindow, kEventWindowActivated}, {kEventClassWindow, kEventWindowDeactivated}, {kEventClassWindow, kEventWindowClose}, }; EventHandlerRef ref; // MW-2005-09-07: Pass the window handle as user data, otherwise 'takewindow' causes problems InstallWindowEventHandler((WindowPtr)window->handle.window, MCS_weh, sizeof(list) / sizeof(EventTypeSpec), list, (WindowPtr)window -> handle . window, &ref); ChangeWindowAttributes((WindowPtr)window->handle.window, 0, kWindowHideOnFullScreenAttribute); updatemodifiedmark(); } start_externals(); }