Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
2026-05-21 DMJC <jcarthew@gmail.com>

* Headers/wayland/WaylandInputServer.h:
* Source/wayland/WaylandInputServer.m:
* Source/wayland/GNUmakefile:
* Headers/wayland/WaylandServer.h:
* Source/wayland/WaylandServer.m:
Add WaylandInputServer, implementing the NSInputServer/NSInputServiceProvider
protocol for the Wayland backend. WaylandServer instantiates it at startup
and delegates all input-method queries (inputMethodStyle, fontSize,
clientWindowRect, preedit/status area accessors) to it via a new
WaylandServer (InputMethod) category. The focused window is tracked via
activeConversationChanged:.

2026-05-21 DMJC <jcarthew@gmail.com>

* configure.ac:
Expand Down
54 changes: 54 additions & 0 deletions Headers/wayland/WaylandInputServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* WaylandInputServer - Keyboard input handling for Wayland backend

Copyright (C) 2024 Free Software Foundation, Inc.

This file is part of the GNUstep Backend.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/

#ifndef _WaylandInputServer_h_INCLUDE
#define _WaylandInputServer_h_INCLUDE

#include <AppKit/NSInputServer.h>

@interface WaylandInputServer : NSInputServer
{
id delegate;
NSString *server_name;
int focused_window_id;
}

- (id) initWithDelegate: (id)aDelegate name: (NSString *)name;
- (void) setFocusedWindowId: (int)windowId;
- (int) focusedWindowId;

@end

@interface WaylandInputServer (InputMethod)
- (NSString *) inputMethodStyle;
- (NSString *) fontSize: (int *)size;
- (BOOL) clientWindowRect: (NSRect *)rect;
- (BOOL) statusArea: (NSRect *)rect;
- (BOOL) preeditArea: (NSRect *)rect;
- (BOOL) preeditSpot: (NSPoint *)p;
- (BOOL) setStatusArea: (NSRect *)rect;
- (BOOL) setPreeditArea: (NSRect *)rect;
- (BOOL) setPreeditSpot: (NSPoint *)p;
@end

#endif /* _WaylandInputServer_h_INCLUDE */
18 changes: 15 additions & 3 deletions Headers/wayland/WaylandServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,24 @@ struct window *get_window_with_id(WaylandConfig *wlconfig, int winid);
WaylandConfig *wlconfig;

BOOL _mouseInitialized;
id inputServer;
}
@end

@interface
WaylandServer (Cursor)
- (void)initializeMouseIfRequired;
@interface WaylandServer (Cursor)
- (void) initializeMouseIfRequired;
@end

@interface WaylandServer (InputMethod)
- (NSString *) inputMethodStyle;
- (NSString *) fontSize: (int *)size;
- (BOOL) clientWindowRect: (NSRect *)rect;
- (BOOL) statusArea: (NSRect *)rect;
- (BOOL) preeditArea: (NSRect *)rect;
- (BOOL) preeditSpot: (NSPoint *)p;
- (BOOL) setStatusArea: (NSRect *)rect;
- (BOOL) setPreeditArea: (NSRect *)rect;
- (BOOL) setPreeditSpot: (NSPoint *)p;
@end

#endif /* _WaylandServer_h_INCLUDE */
1 change: 1 addition & 0 deletions Source/wayland/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ WaylandServer+Keyboard.m \
WaylandServer+Seat.m \
WaylandServer+Xdgshell.m \
WaylandServer+Layershell.m \
WaylandInputServer.m \

ifeq ($(WITH_EGL),yes)
wayland_OBJC_FILES += \
Expand Down
155 changes: 155 additions & 0 deletions Source/wayland/WaylandInputServer.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/* WaylandInputServer - Keyboard input handling for Wayland backend

Copyright (C) 2024 Free Software Foundation, Inc.

This file is part of the GNUstep Backend.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/

#include "config.h"

#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSWindow.h>
#include <GNUstepGUI/GSDisplayServer.h>

#include "wayland/WaylandInputServer.h"

@implementation WaylandInputServer

- (id) initWithDelegate: (id)aDelegate name: (NSString *)name
{
delegate = aDelegate;
ASSIGN(server_name, name);
focused_window_id = 0;
NSDebugLog(@"WaylandInputServer: initialized");
return self;
}

- (void) dealloc
{
DESTROY(server_name);
[super dealloc];
}

- (void) setFocusedWindowId: (int)windowId
{
focused_window_id = windowId;
NSDebugLog(@"WaylandInputServer: focused window id = %d", windowId);
}

- (int) focusedWindowId
{
return focused_window_id;
}

/* NSInputServiceProvider protocol */

- (void) activeConversationChanged: (id)sender
toNewConversation: (long)newConversation
{
[super activeConversationChanged: sender toNewConversation: newConversation];

if ([sender respondsToSelector: @selector(window)] == NO)
return;

/* sender is a text client; -window is checked via respondsToSelector above */
NSWindow *window = [sender performSelector: @selector(window)];
if (window != nil)
{
focused_window_id = [window windowNumber];
NSDebugLog(@"WaylandInputServer: conversation changed, focused window = %d",
focused_window_id);
}
}

- (void) activeConversationWillChange: (id)sender
fromOldConversation: (long)oldConversation
{
[super activeConversationWillChange: sender
fromOldConversation: oldConversation];
}

@end

@implementation WaylandInputServer (InputMethod)

- (NSString *) inputMethodStyle
{
/* Wayland keyboard input is handled directly via XKB in WaylandServer+Keyboard.m.
No input method overlay is used. */
return nil;
}

- (NSString *) fontSize: (int *)size
{
NSString *str;

str = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSFontSize"];
if (!str)
str = @"12";
if (size)
*size = (int) strtol([str cString], NULL, 10);
return str;
}

- (BOOL) clientWindowRect: (NSRect *)rect
{
if (!rect || focused_window_id == 0)
return NO;
NSWindow *window = GSWindowWithNumber(focused_window_id);
if (window == nil)
return NO;
*rect = [window frame];
return YES;
}

- (BOOL) statusArea: (NSRect *)rect
{
return NO;
}

- (BOOL) preeditArea: (NSRect *)rect
{
return NO;
}

- (BOOL) preeditSpot: (NSPoint *)p
{
return NO;
}

- (BOOL) setStatusArea: (NSRect *)rect
{
return NO;
}

- (BOOL) setPreeditArea: (NSRect *)rect
{
return NO;
}

- (BOOL) setPreeditSpot: (NSPoint *)p
{
return NO;
}

@end
63 changes: 63 additions & 0 deletions Source/wayland/WaylandServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <sys/mman.h>

#include "wayland/WaylandServer.h"
#include "wayland/WaylandInputServer.h"
#ifdef HAVE_EGL
#include "wayland/WaylandOpenGL.h"
#endif
Expand Down Expand Up @@ -228,6 +229,9 @@ - (id)_initWaylandContext
@"compositor must support the stable XDG Shell protocol"];
}

inputServer = [[WaylandInputServer allocWithZone: [self zone]]
initWithDelegate: nil name: @"WaylandInput"];

return self;
}

Expand Down Expand Up @@ -275,6 +279,7 @@ - (id)initWithAttributes:(NSDictionary *)info
- (void)dealloc
{
NSDebugLog(@"Destroying Wayland Server");
DESTROY(inputServer);
[super dealloc];
}

Expand Down Expand Up @@ -368,6 +373,64 @@ - (void)beep

@end

@implementation WaylandServer (InputMethod)

- (NSString *) inputMethodStyle
{
return inputServer
? [(WaylandInputServer *) inputServer inputMethodStyle] : nil;
}

- (NSString *) fontSize: (int *)size
{
return inputServer
? [(WaylandInputServer *) inputServer fontSize: size] : nil;
}

- (BOOL) clientWindowRect: (NSRect *)rect
{
return inputServer
? [(WaylandInputServer *) inputServer clientWindowRect: rect] : NO;
}

- (BOOL) statusArea: (NSRect *)rect
{
return inputServer
? [(WaylandInputServer *) inputServer statusArea: rect] : NO;
}

- (BOOL) preeditArea: (NSRect *)rect
{
return inputServer
? [(WaylandInputServer *) inputServer preeditArea: rect] : NO;
}

- (BOOL) preeditSpot: (NSPoint *)p
{
return inputServer
? [(WaylandInputServer *) inputServer preeditSpot: p] : NO;
}

- (BOOL) setStatusArea: (NSRect *)rect
{
return inputServer
? [(WaylandInputServer *) inputServer setStatusArea: rect] : NO;
}

- (BOOL) setPreeditArea: (NSRect *)rect
{
return inputServer
? [(WaylandInputServer *) inputServer setPreeditArea: rect] : NO;
}

- (BOOL) setPreeditSpot: (NSPoint *)p
{
return inputServer
? [(WaylandInputServer *) inputServer setPreeditSpot: p] : NO;
}

@end

@implementation
WaylandServer (WindowOps)

Expand Down
Loading