Implement monitor change functions on GNUstep

* src/nsfns.m (Fns_display_monitor_attributes_list): Fix coding
style.
* src/nsterm.m (nstrace_leave, nstrace_restore_global_trace_state)
(nstrace_fullscreen_type_name): Fix coding style.
(ns_displays_reconfigured, ns_term_init): Make a record of the
previous display attributes list and avoid storing duplicate
events.
([EmacsApp init]): Listen for
NSApplicationDidChangeScreenParametersNotification.
([EmacsApp updateMonitors:]): New method.
(syms_of_nsterm): New staticpro.
This commit is contained in:
Po Lu 2022-05-23 11:13:45 +08:00
parent 20662ecd21
commit 5346b67fc2
2 changed files with 95 additions and 28 deletions

View file

@ -2769,7 +2769,8 @@ Frames are listed from topmost (first) to bottommost (last). */)
}
else
{
// Flip y coordinate as NS has y starting from the bottom.
/* Flip y coordinate as NS screen coordinates originate from
the bottom. */
y = (short) (primary_display_height - fr.size.height - fr.origin.y);
vy = (short) (primary_display_height -
vfr.size.height - vfr.origin.y);
@ -2781,11 +2782,12 @@ Frames are listed from topmost (first) to bottommost (last). */)
m->geom.height = (unsigned short) fr.size.height;
m->work.x = (short) vfr.origin.x;
// y is flipped on NS, so vy - y are pixels missing at the bottom,
// and fr.size.height - vfr.size.height are pixels missing in total.
// Pixels missing at top are
// fr.size.height - vfr.size.height - vy + y.
// work.y is then pixels missing at top + y.
/* y is flipped on NS, so vy - y are pixels missing at the
bottom, and fr.size.height - vfr.size.height are pixels
missing in total.
Pixels missing at top are fr.size.height - vfr.size.height -
vy + y. work.y is then pixels missing at top + y. */
m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
m->work.width = (unsigned short) vfr.size.width;
m->work.height = (unsigned short) vfr.size.height;
@ -2800,13 +2802,14 @@ Frames are listed from topmost (first) to bottommost (last). */)
}
#else
// Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
/* Assume 92 dpi as x-display-mm-height and x-display-mm-width
do. */
m->mm_width = (int) (25.4 * fr.size.width / 92.0);
m->mm_height = (int) (25.4 * fr.size.height / 92.0);
#endif
}
// Primary monitor is always first for NS.
/* Primary monitor is always ordered first for NS. */
attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
0, "NS");

View file

@ -79,6 +79,9 @@ Updated by Christian Limpach (chris@nice.ch)
static EmacsMenu *mainMenu;
#endif
/* The last known monitor attributes list. */
static Lisp_Object last_known_monitors;
/* ==========================================================================
NSTRACE, Trace support.
@ -89,8 +92,8 @@ Updated by Christian Limpach (chris@nice.ch)
/* The following use "volatile" since they can be accessed from
parallel threads. */
volatile int nstrace_num = 0;
volatile int nstrace_depth = 0;
volatile int nstrace_num;
volatile int nstrace_depth;
/* When 0, no trace is emitted. This is used by NSTRACE_WHEN and
NSTRACE_UNLESS to silence functions called.
@ -101,33 +104,41 @@ Updated by Christian Limpach (chris@nice.ch)
volatile int nstrace_enabled_global = 1;
/* Called when nstrace_enabled goes out of scope. */
void nstrace_leave(int * pointer_to_nstrace_enabled)
void
nstrace_leave (int *pointer_to_nstrace_enabled)
{
if (*pointer_to_nstrace_enabled)
{
--nstrace_depth;
}
--nstrace_depth;
}
/* Called when nstrace_saved_enabled_global goes out of scope. */
void nstrace_restore_global_trace_state(int * pointer_to_saved_enabled_global)
void
nstrace_restore_global_trace_state (int *pointer_to_saved_enabled_global)
{
nstrace_enabled_global = *pointer_to_saved_enabled_global;
}
char const * nstrace_fullscreen_type_name (int fs_type)
const char *
nstrace_fullscreen_type_name (int fs_type)
{
switch (fs_type)
{
case -1: return "-1";
case FULLSCREEN_NONE: return "FULLSCREEN_NONE";
case FULLSCREEN_WIDTH: return "FULLSCREEN_WIDTH";
case FULLSCREEN_HEIGHT: return "FULLSCREEN_HEIGHT";
case FULLSCREEN_BOTH: return "FULLSCREEN_BOTH";
case FULLSCREEN_MAXIMIZED: return "FULLSCREEN_MAXIMIZED";
default: return "FULLSCREEN_?????";
case -1:
return "-1";
case FULLSCREEN_NONE:
return "FULLSCREEN_NONE";
case FULLSCREEN_WIDTH:
return "FULLSCREEN_WIDTH";
case FULLSCREEN_HEIGHT:
return "FULLSCREEN_HEIGHT";
case FULLSCREEN_BOTH:
return "FULLSCREEN_BOTH";
case FULLSCREEN_MAXIMIZED:
return "FULLSCREEN_MAXIMIZED";
default:
return "FULLSCREEN_?????";
}
}
#endif
@ -5221,9 +5232,17 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
{
struct input_event ie;
union buffered_input_event *ev;
Lisp_Object new_monitors;
EVENT_INIT (ie);
new_monitors = Fns_display_monitor_attributes_list (Qnil);
if (!NILP (Fequal (new_monitors, last_known_monitors)))
return;
last_known_monitors = new_monitors;
ev = (kbd_store_ptr == kbd_buffer
? kbd_buffer + KBD_BUFFER_SIZE - 1
: kbd_store_ptr - 1);
@ -5601,6 +5620,7 @@ Needs to be here because ns_initialize_display_info () uses AppKit classes.
CGDisplayRegisterReconfigurationCallback (ns_displays_reconfigured,
NULL);
#endif
last_known_monitors = Fns_display_monitor_attributes_list (Qnil);
NSTRACE_MSG ("ns_term_init done");
@ -5642,6 +5662,10 @@ @implementation EmacsApp
- (id)init
{
#ifdef NS_IMPL_GNUSTEP
NSNotificationCenter *notification_center;
#endif
NSTRACE ("[EmacsApp init]");
if ((self = [super init]))
@ -5654,6 +5678,14 @@ - (id)init
#endif
}
#ifdef NS_IMPL_GNUSTEP
notification_center = [NSNotificationCenter defaultCenter];
[notification_center addObserver: self
selector: @selector(updateMonitors:)
name: NSApplicationDidChangeScreenParametersNotification
object: nil];
#endif
return self;
}
@ -5666,11 +5698,11 @@ - (void)run
#define NSAppKitVersionNumber10_9 1265
#endif
if ((int)NSAppKitVersionNumber != NSAppKitVersionNumber10_9)
{
[super run];
return;
}
if ((int) NSAppKitVersionNumber != NSAppKitVersionNumber10_9)
{
[super run];
return;
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@ -5854,6 +5886,36 @@ - (BOOL) openFile: (NSString *)fileName
return YES;
}
#ifdef NS_IMPL_GNUSTEP
- (void) updateMonitors: (NSNotification *) notification
{
struct input_event ie;
union buffered_input_event *ev;
Lisp_Object new_monitors;
EVENT_INIT (ie);
new_monitors = Fns_display_monitor_attributes_list (Qnil);
if (!NILP (Fequal (new_monitors, last_known_monitors)))
return;
last_known_monitors = new_monitors;
ev = (kbd_store_ptr == kbd_buffer
? kbd_buffer + KBD_BUFFER_SIZE - 1
: kbd_store_ptr - 1);
if (kbd_store_ptr != kbd_fetch_ptr
&& ev->ie.kind == MONITORS_CHANGED_EVENT)
return;
ie.kind = MONITORS_CHANGED_EVENT;
XSETTERMINAL (ie.arg, x_display_list->terminal);
kbd_buffer_store_event (&ie);
}
#endif
/* **************************************************************************
@ -10575,4 +10637,6 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
syms_of_nsfont ();
#endif
last_known_monitors = Qnil;
staticpro (&last_known_monitors);
}