> I finally got that working. I have attached a patch (relative to the
> current SVN tree after `make patch`). This only touches macterm.c
> (one line) and macfns.c.
>
> I kept the functionality that returns to the original frame size when
> leaving full-screen mode even though the X port does not do that, as
> it is a very useful thing.
There was a bug in the code that restores the original frame size and
position when leaving full-screen mode. The attached patch should be
better.
Here's an elisp function to retain the old interface, if that's
desirable:
(defun mac-toggle-max-window ()
(interactive)
(set-frame-parameter nil 'fullscreen (if (frame-parameter nil 'fullscreen)
nil
'fullboth)))
Vebjorn
--~--~---------~--~----~------------~-------~--~----~
Carbon Emacs User Group
http://groups.google.com/group/carbon-emacs?hl=en
-~----------~----~----~----~------~----~------~--~---
--- ../../emacs.orig/src/macterm.c 2008-05-16 13:43:47.000000000 -0400
+++ macterm.c 2008-05-21 12:28:28.000000000 -0400
@@ -9540,6 +9540,8 @@
mac_shift_glyphs_for_insert
};
+extern void mac_fullscreen_hook (FRAME_PTR);
+
void
mac_initialize ()
{
@@ -9564,6 +9566,7 @@
condemn_scroll_bars_hook = XTcondemn_scroll_bars;
redeem_scroll_bar_hook = XTredeem_scroll_bar;
judge_scroll_bars_hook = XTjudge_scroll_bars;
+ fullscreen_hook = mac_fullscreen_hook;
scroll_region_ok = 1; /* we'll scroll partial frames */
char_ins_del_ok = 1;
--- ../../emacs.orig/src/macfns.c 2008-05-16 13:43:47.000000000 -0400
+++ macfns.c 2008-05-21 13:13:35.000000000 -0400
@@ -4392,10 +4392,11 @@
typedef struct
{
- Rect bounds;
+ int left, top, pixel_width, pixel_height;
} MacWindowCustomState, **MacWindowCustomStateH;
-#define MAC_WINSTATE_HANDLE_FIELD_PTR(handle, fld) (&((**handle).fld))
+#define MAC_WINSTATE_FIELD_PTR(handle, fld) (&((**handle).fld))
+#define MAC_WINSTATE_FIELD(handle, fld) ((**handle).fld)
void MacReleaseWindowCustomState(
MacWindowCustomStateH h)
@@ -4404,23 +4405,34 @@
free(h);
}
-void MacToggleFullFrame(WindowRef frame);
+static
+mac_set_frame_bounds(f, left, top, pixel_width, pixel_height)
+ FRAME_PTR f;
+ int left, top, pixel_width, pixel_height;
+{
+ int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height);
+ int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width);
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+ Fset_frame_size (frame, make_number (columns), make_number (rows));
+ Fset_frame_position (frame, make_number (left), make_number (top));
+}
+
+extern Lisp_Object Qfullscreen;
+
static pascal void MacOnReconfigMaximizedWindow(
CGDirectDisplayID dispID,
CGDisplayChangeSummaryFlags flags,
void* userInfo)
{
- if (flags & kCGDisplayRemoveFlag)
- {
- /*
- NB: We choose to un-maximize any full-screen frame during a
- display reconfiguration involving the removal of a display.
- */
-
- CGDirectDisplayID inDispID;
- WindowRef frame = (WindowRef) userInfo;
- MacToggleFullFrame(frame);
- }
+ /* Leave full-screen mode when the display is reconfigured (e.g., a
+ display is added or removed, or the resolution is changed)
+ because it is not obvious whether resizing the window is always *
+ the right thing to do. */
+ FRAME_PTR f = (FRAME_PTR) userInfo;
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qfullscreen, Qnil), Qnil));
}
Boolean MacGetWindowCustomState(
@@ -4551,8 +4563,7 @@
}
}
-MacWindowCustomStateH MacSaveWindowCustomState(
- WindowRef wnd)
+MacWindowCustomStateH MacSaveWindowCustomState(WindowRef wnd)
{
OSStatus s;
MacWindowCustomState* state = malloc(sizeof(MacWindowCustomState));
@@ -4561,206 +4572,191 @@
MacRegisterMaxWinCloseHandler(wnd);
- if (noErr != GetWindowBounds(wnd, kWindowStructureRgn, &state->bounds))
- {
+ Rect outer_bounds, inner_bounds;
+ if (noErr != GetWindowBounds(wnd, kWindowStructureRgn, &outer_bounds) ||
+ noErr != GetWindowBounds(wnd, kWindowContentRgn, &inner_bounds))
+ {
error("Error while obtaining window bounds.");
MacReleaseWindowCustomState(h);
return NULL;
- }
- else {
- s = SetWindowProperty(
- wnd,
- MAC_EMACS_CREATOR_CODE,
- MAC_EMACS_WINDOW_PROPTAG_MAXWIN,
- sizeof(MacWindowCustomStateH),
- &h);
-
- if (s != noErr)
- {
- error("Error while saving window bounds.");
- MacReleaseWindowCustomState(h);
- return NULL;
- }
- }
+ }
+ state->left = outer_bounds.left;
+ state->top = outer_bounds.top;
+ state->pixel_width = inner_bounds.right - inner_bounds.left + 1;
+ state->pixel_height = inner_bounds.bottom - inner_bounds.top + 1;
+ s = SetWindowProperty(wnd, MAC_EMACS_CREATOR_CODE,
+ MAC_EMACS_WINDOW_PROPTAG_MAXWIN,
+ sizeof(MacWindowCustomStateH), &h);
+ if (s != noErr)
+ {
+ error("Error while saving window bounds.");
+ MacReleaseWindowCustomState(h);
+ return NULL;
+ }
return h;
}
-/* This function is the workhorse routine for the toggle max-size frame
+/* This function is the workhorse routine for the fullscreen
behavior. */
-/* workaround for compiling on pre-10.4 systems */
+/* Workaround for compiling on pre-10.4 systems. */
#define FNS_kWindowNoTitleBarAttribute 512
-void MacToggleFullFrame(
- WindowRef frame)
+static void
+enter_fullscreen (f)
+ FRAME_PTR f;
{
- OSStatus st;
- CGError e;
- CGDirectDisplayID inDispID;
- MacWindowCustomStateH savedState_h;
-
- if (MacGetWindowCustomState(frame, &savedState_h))
- {
- /* We're un-maximizing the current frame. */
-
- Rect* bounds_p =
- MAC_WINSTATE_HANDLE_FIELD_PTR(savedState_h, bounds);
-
- /*
- Saved window state only exists when frame has already been
- maximized, so we need to restore the window to its initial,
- pre-maximized state and then remove the saved window state
- from the window.
- */
-
- /* Enable title bar and resizability */
- st = ChangeWindowAttributes(
- frame,
- kWindowResizableAttribute,
- FNS_kWindowNoTitleBarAttribute);
- if (st != noErr)
- {
- error ("Error during unmaximize: couldn't change window attributes.");
- goto unmax_cleanup;
- }
-
- /* Reset window size */
- st = SetWindowBounds(frame, kWindowStructureRgn, bounds_p);
- if (st != noErr)
- {
- error ("Error during unmaximize: couldn't reset window bounds.");
- goto unmax_cleanup;
- }
+ OSStatus st;
- MacHandleMenuBarBehavior(false,frame);
+ WindowRef mac_window = FRAME_MAC_WINDOW (f);
- /* Resize and/or move the frame as needed in case the saved
- bounds aren't acceptable for the current display */
+ MacWindowCustomStateH savedState_h = MacSaveWindowCustomState (mac_window);
+ if (savedState_h == NULL)
+ {
+ UNBLOCK_INPUT;
+ error ("Error during maximize: couldn't save window custom state.");
+ }
- st = ConstrainWindowToScreen(
- frame,
- kWindowStructureRgn,
- kWindowConstrainStandardOptions,
- NULL,
- NULL);
+ /* Remove title bar & resizability from the window */
+ st = ChangeWindowAttributes (mac_window, FNS_kWindowNoTitleBarAttribute,
+ kWindowResizableAttribute);
+ if (st != noErr)
+ {
+ UNBLOCK_INPUT;
+ MacReleaseWindowCustomState (savedState_h);
+ error ("Error during maximize: couldn't set window attributes.");
+ }
- if (st != noErr)
- {
- error("Error during unmaximize: couldn't constrain window.");
- goto unmax_cleanup;
- }
+ short mbarHeight = MacHandleMenuBarBehavior (true, mac_window);
- /* Toss the saved data */
- st = RemoveWindowProperty(
- frame,
- MAC_EMACS_CREATOR_CODE,
- MAC_EMACS_WINDOW_PROPTAG_MAXWIN);
- if (st != noErr)
- {
- error ("Error during unmaximize: couldn't remove window state.");
- goto unmax_cleanup;
- }
-
- unmax_cleanup:
- MacReleaseWindowCustomState(savedState_h);
-
- /* Unregister the display reconfiguration cb */
- e = CGDisplayRemoveReconfigurationCallback(
- MacOnReconfigMaximizedWindow,
- frame);
- if (e != noErr)
- error ("Error during unmaximize: couldn't unregister cb");
+ /* Enlarge the window to the screen bounds (unless the user
+ chose to only maximize width or height), leaving room for the
+ menubar to if it is visible (this can be controlled by the
+ user via mac-autohide-menubar-on-maximize */
+ CGDirectDisplayID inDispID;
+ st = MacGetDisplayIdForWindow (mac_window, &inDispID);
+ if (st != noErr)
+ {
+ UNBLOCK_INPUT;
+ MacReleaseWindowCustomState (savedState_h);
+ error ("Error during maximize: couldn't get display id");
}
- else
+ int left = MAC_WINSTATE_FIELD (savedState_h, left);
+ int top = MAC_WINSTATE_FIELD (savedState_h, top);
+ int pixel_width = MAC_WINSTATE_FIELD (savedState_h, pixel_width);
+ int pixel_height = MAC_WINSTATE_FIELD (savedState_h, pixel_height);
+ Rect screen_bounds = MacConvertCGRectToRect (CGDisplayBounds(inDispID));
+ screen_bounds.top += mbarHeight;
+ if (f->want_fullscreen & FULLSCREEN_HEIGHT)
{
- /* We're maximizing the current frame. */
-
- Rect screenBnds;
- CGDirectDisplayID inDispID;
- short mbarHeight;
+ top = screen_bounds.top;
+ pixel_height = screen_bounds.bottom - top + 1;
+ }
+ if (f->want_fullscreen & FULLSCREEN_WIDTH)
+ {
+ left = screen_bounds.left;
+ pixel_width = screen_bounds.right - left + 1;
+ }
+ mac_set_frame_bounds (f, left, top, pixel_width, pixel_height);
+
+ /* Register a callback to restore the window to its old size when
+ the displays are reconfigured; if we don't do this, we can end
+ up with a maximized window that is larger than the current
+ display. The cb is unregistered on un-maximize. */
+ CGError e = CGDisplayRegisterReconfigurationCallback
+ (MacOnReconfigMaximizedWindow, f);
+ if (e != noErr)
+ {
+ UNBLOCK_INPUT;
+ MacReleaseWindowCustomState (savedState_h);
+ error ("Error during maximize: couldn't register reconfig cb");
+ }
+ f->want_fullscreen = FULLSCREEN_NONE;
+}
- savedState_h = MacSaveWindowCustomState(frame);
- if (savedState_h == NULL)
- return;
+static void
+leave_fullscreen (f)
+ FRAME_PTR f;
+{
+ OSStatus st;
- mbarHeight = MacHandleMenuBarBehavior(true, frame);
-
- /* Remove title bar & resizability from the window */
- st = ChangeWindowAttributes(
- frame,
- FNS_kWindowNoTitleBarAttribute,
- kWindowResizableAttribute);
- if (st != noErr)
- {
- error("Error during maximize: couldn't set window attributes.");
- goto max_cleanup;
- }
+ WindowRef mac_window = FRAME_MAC_WINDOW (f);
- st = MacGetDisplayIdForWindow(frame, &inDispID);
- if (st != noErr)
- {
- error ("Error during maximize: couldn't get display id");
- goto max_cleanup;
- }
+ /* Enable title bar and resizability */
+ st = ChangeWindowAttributes (mac_window, kWindowResizableAttribute,
+ FNS_kWindowNoTitleBarAttribute);
+ if (st != noErr)
+ {
+ UNBLOCK_INPUT;
+ error ("Error during unmaximize: couldn't change window attributes.");
+ }
- /* Maximize the window to the screen bounds, , leaving room
- for the menubar to if it is visible (this can be
- controlled by the user via mac-autohide-menubar-on-maximize */
+ /* Reset window size */
+ MacWindowCustomStateH savedState_h;
+ if (!MacGetWindowCustomState (mac_window, &savedState_h))
+ {
+ UNBLOCK_INPUT;
+ error ("Error during unmaximize: couldn't get window custom state.");
+ }
+ int left = MAC_WINSTATE_FIELD (savedState_h, left);
+ int top = MAC_WINSTATE_FIELD (savedState_h, top);
+ int pixel_width = MAC_WINSTATE_FIELD (savedState_h, pixel_width);
+ int pixel_height = MAC_WINSTATE_FIELD (savedState_h, pixel_height);
+ mac_set_frame_bounds (f, left, top, pixel_width, pixel_height);
- screenBnds = MacConvertCGRectToRect(CGDisplayBounds(inDispID));
- screenBnds.top += mbarHeight;
+ MacReleaseWindowCustomState (savedState_h);
+ if (st != noErr)
+ {
+ UNBLOCK_INPUT;
+ error ("Error during unmaximize: couldn't reset window bounds.");
+ }
- st = SetWindowBounds(frame, kWindowStructureRgn, &screenBnds);
- if (st != noErr)
- {
- error ("Error during maximize: couldn't set window bounds.");
- goto max_cleanup;
- }
-
- /*
- Register a callback to restore the window to its old size when
- the displays are reconfigured; if we don't do this, we can end
- up with a maximized window that is larger than the current
- display. The cb is unregistered on un-maximize.
- */
-
- e = CGDisplayRegisterReconfigurationCallback(
- MacOnReconfigMaximizedWindow,
- frame);
- if (e != noErr)
- {
- error ("Error during maximize: couldn't register reconfig cb");
- goto max_cleanup;
- }
+ MacHandleMenuBarBehavior (false, mac_window);
- goto max_done;
-
- max_cleanup:
- MacReleaseWindowCustomState(savedState_h);
+ /* Resize and/or move the mac_window as needed in case the saved
+ bounds aren't acceptable for the current display */
+ st = ConstrainWindowToScreen (mac_window, kWindowStructureRgn,
+ kWindowConstrainStandardOptions,
+ NULL, NULL);
+ if (st != noErr)
+ {
+ UNBLOCK_INPUT;
+ error("Error during unmaximize: couldn't constrain window.");
+ }
- max_done:
- return;
+ f->want_fullscreen = FULLSCREEN_NONE;
+ /* Toss the saved data */
+ st = RemoveWindowProperty (mac_window, MAC_EMACS_CREATOR_CODE,
+ MAC_EMACS_WINDOW_PROPTAG_MAXWIN);
+ if (st != noErr)
+ {
+ UNBLOCK_INPUT;
+ error ("Error during unmaximize: couldn't remove window state.");
}
+
+ /* Unregister the display reconfiguration cb */
+ CGError e = CGDisplayRemoveReconfigurationCallback
+ (MacOnReconfigMaximizedWindow, f);
+ if (e != noErr)
+ error ("Error during unmaximize: couldn't unregister callback.");
}
-DEFUN ("mac-toggle-full-frame", Fmac_toggle_full_frame, Smac_toggle_full_frame, 0, 0, "",
- doc: /* Makes the current frame use as much of the display as
-possible, or reverts it to its previous size and position if already
-maximized. If mac-autohide-menubar-on-maximize is non-nil, maximized
-frames auto-hide the menubar.*/)
- ()
+void
+mac_fullscreen_hook (f)
+ FRAME_PTR f;
{
- if (!EQ (Vwindow_system, intern ("mac")))
- return Qnil;
- BLOCK_INPUT;
-
- WindowRef frame = GetUserFocusWindow();
- MacToggleFullFrame(frame);
+ if (!f->async_visible)
+ return;
- UNBLOCK_INPUT;
- return Qnil;
+ BLOCK_INPUT;
+ if (f->want_fullscreen == FULLSCREEN_NONE)
+ leave_fullscreen(f);
+ else
+ enter_fullscreen(f);
+ UNBLOCK_INPUT;
}
+
/* === End support for maximizing frames to the full display. === */
#endif /* MAC_OSX && TARGET_API_MAC_CARBON */
@@ -5163,7 +5159,6 @@
#if TARGET_API_MAC_CARBON
defsubr (&Sx_file_dialog);
#if MAC_OSX
- defsubr (&Smac_toggle_full_frame);
defsubr (&Smac_show_menu_bar);
defsubr (&Smac_hide_menu_bar);
defsubr (&Smac_dialog);