Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0aef2c3612 | ||
|
|
9464f334b5 | ||
|
|
1c9643249d | ||
|
|
8236e01a9f | ||
|
|
de1616baee | ||
|
|
964b9da519 | ||
|
|
364abb8702 | ||
|
|
1650c0289d | ||
|
|
97002d81a7 | ||
|
|
18ecd2ccad | ||
|
|
ba7ec31927 | ||
|
|
72a9e5edad | ||
|
|
43108beb5b | ||
|
|
63521cb9a7 | ||
|
|
48f21f434f | ||
|
|
90c7f51d8a | ||
|
|
5d3a382eb7 | ||
|
|
b895741422 | ||
|
|
66ce42b7d2 | ||
|
|
f4f20c9255 | ||
|
|
f71979dcb3 | ||
|
|
81ce8d659e | ||
|
|
732f779606 | ||
|
|
a5c518bf71 |
No files matched your search
@@ -659,7 +659,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
|||||||
match spec.platform:
|
match spec.platform:
|
||||||
case SdlPlatform.FreeBSD:
|
case SdlPlatform.FreeBSD:
|
||||||
job.cpactions_os = "freebsd"
|
job.cpactions_os = "freebsd"
|
||||||
job.cpactions_version = "13.3"
|
job.cpactions_version = "14.2"
|
||||||
job.cpactions_arch = "x86-64"
|
job.cpactions_arch = "x86-64"
|
||||||
job.cpactions_setup_cmd = "sudo pkg update"
|
job.cpactions_setup_cmd = "sudo pkg update"
|
||||||
job.cpactions_install_cmd = "sudo pkg install -y cmake ninja pkgconf libXcursor libXext libXinerama libXi libXfixes libXrandr libXScrnSaver libXxf86vm wayland wayland-protocols libxkbcommon mesa-libs libglvnd evdev-proto libinotify alsa-lib jackit pipewire pulseaudio sndio dbus zh-fcitx ibus libudev-devd"
|
job.cpactions_install_cmd = "sudo pkg install -y cmake ninja pkgconf libXcursor libXext libXinerama libXi libXfixes libXrandr libXScrnSaver libXxf86vm wayland wayland-protocols libxkbcommon mesa-libs libglvnd evdev-proto libinotify alsa-lib jackit pipewire pulseaudio sndio dbus zh-fcitx ibus libudev-devd"
|
||||||
@@ -669,7 +669,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
|||||||
))
|
))
|
||||||
case SdlPlatform.NetBSD:
|
case SdlPlatform.NetBSD:
|
||||||
job.cpactions_os = "netbsd"
|
job.cpactions_os = "netbsd"
|
||||||
job.cpactions_version = "10.0"
|
job.cpactions_version = "10.1"
|
||||||
job.cpactions_arch = "x86-64"
|
job.cpactions_arch = "x86-64"
|
||||||
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
|
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
|
||||||
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
|
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
|
||||||
|
|||||||
@@ -264,11 +264,11 @@ jobs:
|
|||||||
- name: 'Build (cross-platform-actions, BSD)'
|
- name: 'Build (cross-platform-actions, BSD)'
|
||||||
id: cpactions
|
id: cpactions
|
||||||
if: ${{ matrix.platform.cpactions }}
|
if: ${{ matrix.platform.cpactions }}
|
||||||
uses: cross-platform-actions/action@v0.25.0
|
uses: cross-platform-actions/action@v0.27.0
|
||||||
with:
|
with:
|
||||||
operating_system: ${{ matrix.platform.cpactions-os }}
|
operating_system: '${{ matrix.platform.cpactions-os }}'
|
||||||
architecture: ${{ matrix.platform.cpactions-arch }}
|
architecture: '${{ matrix.platform.cpactions-arch }}'
|
||||||
version: ${{ matrix.platform.cpactions-version }}
|
version: '${{ matrix.platform.cpactions-version }}'
|
||||||
run: |
|
run: |
|
||||||
${{ matrix.platform.cpactions-setup-cmd }}
|
${{ matrix.platform.cpactions-setup-cmd }}
|
||||||
${{ matrix.platform.cpactions-install-cmd }}
|
${{ matrix.platform.cpactions-install-cmd }}
|
||||||
|
|||||||
+1
-1
@@ -87,7 +87,7 @@ endif()
|
|||||||
# See docs/release_checklist.md
|
# See docs/release_checklist.md
|
||||||
set(SDL_MAJOR_VERSION 2)
|
set(SDL_MAJOR_VERSION 2)
|
||||||
set(SDL_MINOR_VERSION 30)
|
set(SDL_MINOR_VERSION 30)
|
||||||
set(SDL_MICRO_VERSION 11)
|
set(SDL_MICRO_VERSION 12)
|
||||||
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
|
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
|
||||||
|
|
||||||
# Set defaults preventing destination file conflicts
|
# Set defaults preventing destination file conflicts
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
LIBNAME = SDL2
|
LIBNAME = SDL2
|
||||||
MAJOR_VERSION = 2
|
MAJOR_VERSION = 2
|
||||||
MINOR_VERSION = 30
|
MINOR_VERSION = 30
|
||||||
MICRO_VERSION = 11
|
MICRO_VERSION = 12
|
||||||
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
|
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
|
||||||
DESCRIPTION = Simple DirectMedia Layer 2
|
DESCRIPTION = Simple DirectMedia Layer 2
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
LIBNAME = SDL2
|
LIBNAME = SDL2
|
||||||
MAJOR_VERSION = 2
|
MAJOR_VERSION = 2
|
||||||
MINOR_VERSION = 30
|
MINOR_VERSION = 30
|
||||||
MICRO_VERSION = 11
|
MICRO_VERSION = 12
|
||||||
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
|
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
|
||||||
|
|
||||||
LIBHOME = .
|
LIBHOME = .
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>FMWK</string>
|
<string>FMWK</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.30.11</string>
|
<string>2.30.12</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>SDLX</string>
|
<string>SDLX</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2.30.11</string>
|
<string>2.30.12</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -9729,7 +9729,7 @@
|
|||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEPLOYMENT_POSTPROCESSING = YES;
|
DEPLOYMENT_POSTPROCESSING = YES;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
||||||
DYLIB_CURRENT_VERSION = 3001.11.0;
|
DYLIB_CURRENT_VERSION = 3001.12.0;
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
GCC_ALTIVEC_EXTENSIONS = YES;
|
GCC_ALTIVEC_EXTENSIONS = YES;
|
||||||
@@ -9770,7 +9770,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||||
MARKETING_VERSION = 2.30.11;
|
MARKETING_VERSION = 2.30.12;
|
||||||
OTHER_LDFLAGS = "-liconv";
|
OTHER_LDFLAGS = "-liconv";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
@@ -9814,7 +9814,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
||||||
DYLIB_CURRENT_VERSION = 3001.11.0;
|
DYLIB_CURRENT_VERSION = 3001.12.0;
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
@@ -9856,7 +9856,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||||
MARKETING_VERSION = 2.30.11;
|
MARKETING_VERSION = 2.30.12;
|
||||||
OTHER_LDFLAGS = "-liconv";
|
OTHER_LDFLAGS = "-liconv";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -10063,7 +10063,7 @@
|
|||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
||||||
DYLIB_CURRENT_VERSION = 3001.11.0;
|
DYLIB_CURRENT_VERSION = 3001.12.0;
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
@@ -10115,7 +10115,7 @@
|
|||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
DYLIB_COMPATIBILITY_VERSION = 3001.0.0;
|
||||||
DYLIB_CURRENT_VERSION = 3001.11.0;
|
DYLIB_CURRENT_VERSION = 3001.12.0;
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Title SDL 2.30.11
|
Title SDL 2.30.12
|
||||||
Version 1
|
Version 1
|
||||||
Description SDL Library for Mac OS X (http://www.libsdl.org)
|
Description SDL Library for Mac OS X (http://www.libsdl.org)
|
||||||
DefaultLocation /Library/Frameworks
|
DefaultLocation /Library/Frameworks
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||||||
private static final String TAG = "SDL";
|
private static final String TAG = "SDL";
|
||||||
private static final int SDL_MAJOR_VERSION = 2;
|
private static final int SDL_MAJOR_VERSION = 2;
|
||||||
private static final int SDL_MINOR_VERSION = 30;
|
private static final int SDL_MINOR_VERSION = 30;
|
||||||
private static final int SDL_MICRO_VERSION = 11;
|
private static final int SDL_MICRO_VERSION = 12;
|
||||||
/*
|
/*
|
||||||
// Display InputType.SOURCE/CLASS of events and devices
|
// Display InputType.SOURCE/CLASS of events and devices
|
||||||
//
|
//
|
||||||
|
|||||||
+133
-40
@@ -37,6 +37,8 @@ logger = logging.getLogger(__name__)
|
|||||||
GIT_HASH_FILENAME = ".git-hash"
|
GIT_HASH_FILENAME = ".git-hash"
|
||||||
REVISION_TXT = "REVISION.txt"
|
REVISION_TXT = "REVISION.txt"
|
||||||
|
|
||||||
|
RE_ILLEGAL_MINGW_LIBRARIES = re.compile(r"(?:lib)?(?:gcc|(?:std)?c[+][+]|(?:win)?pthread).*", flags=re.I)
|
||||||
|
|
||||||
|
|
||||||
def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime:
|
def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime:
|
||||||
try:
|
try:
|
||||||
@@ -339,6 +341,12 @@ class ArchiveFileTree:
|
|||||||
def add_file(self, file: NodeInArchive):
|
def add_file(self, file: NodeInArchive):
|
||||||
self._tree[file.arcpath] = file
|
self._tree[file.arcpath] = file
|
||||||
|
|
||||||
|
def __iter__(self) -> typing.Iterable[NodeInArchive]:
|
||||||
|
yield from self._tree.values()
|
||||||
|
|
||||||
|
def __contains__(self, value: str) -> bool:
|
||||||
|
return value in self._tree
|
||||||
|
|
||||||
def get_latest_mod_time(self) -> datetime.datetime:
|
def get_latest_mod_time(self) -> datetime.datetime:
|
||||||
return max(item.time for item in self._tree.values() if item.time)
|
return max(item.time for item in self._tree.values() if item.time)
|
||||||
|
|
||||||
@@ -526,6 +534,18 @@ class SourceCollector:
|
|||||||
return path_times
|
return path_times
|
||||||
|
|
||||||
|
|
||||||
|
class AndroidApiVersion:
|
||||||
|
def __init__(self, name: str, ints: tuple[int, ...]):
|
||||||
|
self.name = name
|
||||||
|
self.ints = ints
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
|
||||||
|
|
||||||
|
ANDROID_ABI_EXTRA_LINK_OPTIONS = {
|
||||||
|
"arm64-v8a": "-Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384",
|
||||||
|
}
|
||||||
|
|
||||||
class Releaser:
|
class Releaser:
|
||||||
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
|
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
|
||||||
self.release_info = release_info
|
self.release_info = release_info
|
||||||
@@ -586,12 +606,22 @@ class Releaser:
|
|||||||
def create_source_archives(self) -> None:
|
def create_source_archives(self) -> None:
|
||||||
source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter)
|
source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter)
|
||||||
print(f"Collecting sources of {self.project}...")
|
print(f"Collecting sources of {self.project}...")
|
||||||
archive_tree = source_collector.get_archive_file_tree()
|
archive_tree: ArchiveFileTree = source_collector.get_archive_file_tree()
|
||||||
latest_mod_time = archive_tree.get_latest_mod_time()
|
latest_mod_time = archive_tree.get_latest_mod_time()
|
||||||
archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time))
|
archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time))
|
||||||
archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time))
|
archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time))
|
||||||
archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time)
|
archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time)
|
||||||
|
|
||||||
|
if "Makefile.am" in archive_tree:
|
||||||
|
patched_time = latest_mod_time + datetime.timedelta(minutes=1)
|
||||||
|
print(f"Makefile.am detected -> touching aclocal.m4, */Makefile.in, configure")
|
||||||
|
for node_data in archive_tree:
|
||||||
|
arc_name = os.path.basename(node_data.arcpath)
|
||||||
|
arc_name_we, arc_name_ext = os.path.splitext(arc_name)
|
||||||
|
if arc_name in ("aclocal.m4", "configure", "Makefile.in"):
|
||||||
|
print(f"Bumping time of {node_data.arcpath}")
|
||||||
|
node_data.time = patched_time
|
||||||
|
|
||||||
archive_base = f"{self.project}-{self.version}"
|
archive_base = f"{self.project}-{self.version}"
|
||||||
zip_path = self.dist_path / f"{archive_base}.zip"
|
zip_path = self.dist_path / f"{archive_base}.zip"
|
||||||
tgz_path = self.dist_path / f"{archive_base}.tar.gz"
|
tgz_path = self.dist_path / f"{archive_base}.tar.gz"
|
||||||
@@ -668,6 +698,15 @@ class Releaser:
|
|||||||
def git_hash_data(self) -> bytes:
|
def git_hash_data(self) -> bytes:
|
||||||
return f"{self.commit}\n".encode()
|
return f"{self.commit}\n".encode()
|
||||||
|
|
||||||
|
def verify_mingw_library(self, triplet: str, path: Path):
|
||||||
|
objdump_output = self.executer.check_output([f"{triplet}-objdump", "-p", str(path)])
|
||||||
|
libraries = re.findall(r"DLL Name: ([^\n]+)", objdump_output)
|
||||||
|
logger.info("%s (%s) libraries: %r", path, triplet, libraries)
|
||||||
|
illegal_libraries = list(filter(RE_ILLEGAL_MINGW_LIBRARIES.match, libraries))
|
||||||
|
logger.error("Detected 'illegal' libraries: %r", illegal_libraries)
|
||||||
|
if illegal_libraries:
|
||||||
|
raise Exception(f"{path} links to illegal libraries: {illegal_libraries}")
|
||||||
|
|
||||||
def create_mingw_archives(self) -> None:
|
def create_mingw_archives(self) -> None:
|
||||||
build_type = "Release"
|
build_type = "Release"
|
||||||
build_parent_dir = self.root / "build-mingw"
|
build_parent_dir = self.root / "build-mingw"
|
||||||
@@ -764,7 +803,6 @@ class Releaser:
|
|||||||
f"--includedir=${{prefix}}/include",
|
f"--includedir=${{prefix}}/include",
|
||||||
f"--libdir=${{prefix}}/lib",
|
f"--libdir=${{prefix}}/lib",
|
||||||
f"--bindir=${{prefix}}/bin",
|
f"--bindir=${{prefix}}/bin",
|
||||||
f"--exec-prefix=${{prefix}}/bin",
|
|
||||||
f"--host={triplet}",
|
f"--host={triplet}",
|
||||||
f"--build=x86_64-none-linux-gnu",
|
f"--build=x86_64-none-linux-gnu",
|
||||||
"CFLAGS=-O2",
|
"CFLAGS=-O2",
|
||||||
@@ -772,9 +810,10 @@ class Releaser:
|
|||||||
"LDFLAGS=-Wl,-s",
|
"LDFLAGS=-Wl,-s",
|
||||||
] + extra_args, cwd=build_path, env=new_env)
|
] + extra_args, cwd=build_path, env=new_env)
|
||||||
with self.section_printer.group(f"Build MinGW {triplet} (autotools)"):
|
with self.section_printer.group(f"Build MinGW {triplet} (autotools)"):
|
||||||
self.executer.run(["make", "V=1", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
|
self.executer.run(["make", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
|
||||||
with self.section_printer.group(f"Install MinGW {triplet} (autotools)"):
|
with self.section_printer.group(f"Install MinGW {triplet} (autotools)"):
|
||||||
self.executer.run(["make", "install"], cwd=build_path, env=new_env)
|
self.executer.run(["make", "install"], cwd=build_path, env=new_env)
|
||||||
|
self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll")
|
||||||
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
|
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
|
||||||
|
|
||||||
print("Recording arch-dependent extra files for MinGW development archive ...")
|
print("Recording arch-dependent extra files for MinGW development archive ...")
|
||||||
@@ -830,6 +869,7 @@ class Releaser:
|
|||||||
self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env)
|
self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env)
|
||||||
with self.section_printer.group(f"Install MinGW {triplet} (CMake)"):
|
with self.section_printer.group(f"Install MinGW {triplet} (CMake)"):
|
||||||
self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env)
|
self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env)
|
||||||
|
self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll")
|
||||||
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
|
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
|
||||||
|
|
||||||
print("Recording arch-dependent extra files for MinGW development archive ...")
|
print("Recording arch-dependent extra files for MinGW development archive ...")
|
||||||
@@ -857,22 +897,25 @@ class Releaser:
|
|||||||
self.artifacts["mingw-devel-tar-gz"] = tgz_path
|
self.artifacts["mingw-devel-tar-gz"] = tgz_path
|
||||||
self.artifacts["mingw-devel-tar-xz"] = txz_path
|
self.artifacts["mingw-devel-tar-xz"] = txz_path
|
||||||
|
|
||||||
def _detect_android_api(self, android_home: str) -> typing.Optional[int]:
|
def _detect_android_api(self, android_home: str) -> typing.Optional[AndroidApiVersion]:
|
||||||
platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*"))
|
platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*"))
|
||||||
re_platform = re.compile("android-([0-9]+)")
|
re_platform = re.compile("^android-([0-9]+)(?:-ext([0-9]+))?$")
|
||||||
platform_versions = []
|
platform_versions: list[AndroidApiVersion] = []
|
||||||
for platform_dir in platform_dirs:
|
for platform_dir in platform_dirs:
|
||||||
logger.debug("Found Android Platform SDK: %s", platform_dir)
|
logger.debug("Found Android Platform SDK: %s", platform_dir)
|
||||||
|
if not (platform_dir / "android.jar").is_file():
|
||||||
|
logger.debug("Skipping SDK, missing android.jar")
|
||||||
|
continue
|
||||||
if m:= re_platform.match(platform_dir.name):
|
if m:= re_platform.match(platform_dir.name):
|
||||||
platform_versions.append(int(m.group(1)))
|
platform_versions.append(AndroidApiVersion(name=platform_dir.name, ints=(int(m.group(1)), int(m.group(2) or 0))))
|
||||||
platform_versions.sort()
|
platform_versions.sort(key=lambda v: v.ints)
|
||||||
logger.info("Available platform versions: %s", platform_versions)
|
logger.info("Available platform versions: %s", platform_versions)
|
||||||
platform_versions = list(filter(lambda v: v >= self._android_api_minimum, platform_versions))
|
platform_versions = list(filter(lambda v: v.ints >= self._android_api_minimum.ints, platform_versions))
|
||||||
logger.info("Valid platform versions (>=%d): %s", self._android_api_minimum, platform_versions)
|
logger.info("Valid platform versions (>=%s): %s", self._android_api_minimum.ints, platform_versions)
|
||||||
if not platform_versions:
|
if not platform_versions:
|
||||||
return None
|
return None
|
||||||
android_api = platform_versions[0]
|
android_api = platform_versions[0]
|
||||||
logger.info("Selected API version %d", android_api)
|
logger.info("Selected API version %s", android_api)
|
||||||
return android_api
|
return android_api
|
||||||
|
|
||||||
def _get_prefab_json_text(self) -> str:
|
def _get_prefab_json_text(self) -> str:
|
||||||
@@ -896,8 +939,19 @@ class Releaser:
|
|||||||
return json.dumps(module_json_dict, indent=4)
|
return json.dumps(module_json_dict, indent=4)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _android_api_minimum(self):
|
def _android_api_minimum(self) -> AndroidApiVersion:
|
||||||
return self.release_info["android"]["api-minimum"]
|
value = self.release_info["android"]["api-minimum"]
|
||||||
|
if isinstance(value, int):
|
||||||
|
ints = (value, )
|
||||||
|
elif isinstance(value, str):
|
||||||
|
ints = tuple(split("."))
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid android.api-minimum: must be X or X.Y")
|
||||||
|
match len(ints):
|
||||||
|
case 1: name = f"android-{ints[0]}"
|
||||||
|
case 2: name = f"android-{ints[0]}-ext-{ints[1]}"
|
||||||
|
case _: raise ValueError("Invalid android.api-minimum: must be X or X.Y")
|
||||||
|
return AndroidApiVersion(name=name, ints=ints)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _android_api_target(self):
|
def _android_api_target(self):
|
||||||
@@ -910,7 +964,7 @@ class Releaser:
|
|||||||
def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str:
|
def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str:
|
||||||
abi_json_dict = {
|
abi_json_dict = {
|
||||||
"abi": abi,
|
"abi": abi,
|
||||||
"api": self._android_api_minimum,
|
"api": self._android_api_minimum.ints[0],
|
||||||
"ndk": self._android_ndk_minimum,
|
"ndk": self._android_ndk_minimum,
|
||||||
"stl": "c++_shared" if cpp else "none",
|
"stl": "c++_shared" if cpp else "none",
|
||||||
"static": not shared,
|
"static": not shared,
|
||||||
@@ -923,7 +977,7 @@ class Releaser:
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.libsdl.android.{self.project}" android:versionCode="1"
|
package="org.libsdl.android.{self.project}" android:versionCode="1"
|
||||||
android:versionName="1.0">
|
android:versionName="1.0">
|
||||||
<uses-sdk android:minSdkVersion="{self._android_api_minimum}"
|
<uses-sdk android:minSdkVersion="{self._android_api_minimum.ints[0]}"
|
||||||
android:targetSdkVersion="{self._android_api_target}" />
|
android:targetSdkVersion="{self._android_api_target}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
""")
|
""")
|
||||||
@@ -933,7 +987,8 @@ class Releaser:
|
|||||||
if not cmake_toolchain_file.exists():
|
if not cmake_toolchain_file.exists():
|
||||||
logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file)
|
logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file)
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
aar_path = self.dist_path / f"{self.project}-{self.version}.aar"
|
aar_path = self.root / "build-android" / f"{self.project}-{self.version}.aar"
|
||||||
|
android_dist_path = self.dist_path / f"{self.project}-devel-{self.version}-android.zip"
|
||||||
android_abis = self.release_info["android"]["abis"]
|
android_abis = self.release_info["android"]["abis"]
|
||||||
java_jars_added = False
|
java_jars_added = False
|
||||||
module_data_added = False
|
module_data_added = False
|
||||||
@@ -941,16 +996,27 @@ class Releaser:
|
|||||||
shutil.rmtree(android_deps_path, ignore_errors=True)
|
shutil.rmtree(android_deps_path, ignore_errors=True)
|
||||||
|
|
||||||
for dep, depinfo in self.release_info["android"].get("dependencies", {}).items():
|
for dep, depinfo in self.release_info["android"].get("dependencies", {}).items():
|
||||||
android_aar = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
|
dep_devel_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
|
||||||
with self.section_printer.group(f"Extracting Android dependency {dep} ({android_aar.name})"):
|
|
||||||
self.executer.run([sys.executable, str(android_aar), "-o", str(android_deps_path)])
|
dep_extract_path = self.deps_path / f"extract/android/{dep}"
|
||||||
|
shutil.rmtree(dep_extract_path, ignore_errors=True)
|
||||||
|
dep_extract_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
with self.section_printer.group(f"Extracting Android dependency {dep} ({dep_devel_zip})"):
|
||||||
|
with zipfile.ZipFile(dep_devel_zip, "r") as zf:
|
||||||
|
zf.extractall(dep_extract_path)
|
||||||
|
|
||||||
|
dep_devel_aar = dep_extract_path / glob.glob("*.aar", root_dir=dep_extract_path)[0]
|
||||||
|
self.executer.run([sys.executable, str(dep_devel_aar), "-o", str(android_deps_path)])
|
||||||
|
|
||||||
for module_name, module_info in self.release_info["android"]["modules"].items():
|
for module_name, module_info in self.release_info["android"]["modules"].items():
|
||||||
assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type"
|
assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type"
|
||||||
|
|
||||||
archive_file_tree = ArchiveFileTree()
|
aar_file_tree = ArchiveFileTree()
|
||||||
|
android_devel_file_tree = ArchiveFileTree()
|
||||||
|
|
||||||
for android_abi in android_abis:
|
for android_abi in android_abis:
|
||||||
|
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
|
||||||
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
|
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
|
||||||
build_dir = self.root / "build-android" / f"{android_abi}-build"
|
build_dir = self.root / "build-android" / f"{android_abi}-build"
|
||||||
install_dir = self.root / "install-android" / f"{android_abi}-install"
|
install_dir = self.root / "install-android" / f"{android_abi}-install"
|
||||||
@@ -961,8 +1027,11 @@ class Releaser:
|
|||||||
"cmake",
|
"cmake",
|
||||||
"-S", str(self.root),
|
"-S", str(self.root),
|
||||||
"-B", str(build_dir),
|
"-B", str(build_dir),
|
||||||
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
# NDK 21e does not support -ffile-prefix-map
|
||||||
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
# f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||||
|
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||||
|
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
|
||||||
|
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
|
||||||
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
|
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
|
||||||
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
|
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
|
||||||
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
|
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
|
||||||
@@ -999,20 +1068,20 @@ class Releaser:
|
|||||||
assert library.suffix in (".so", ".a")
|
assert library.suffix in (".so", ".a")
|
||||||
assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}"
|
assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}"
|
||||||
arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}"
|
arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}"
|
||||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
|
||||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
|
||||||
|
|
||||||
if not module_data_added:
|
if not module_data_added:
|
||||||
library_name = None
|
library_name = None
|
||||||
if module_info["type"] == "library":
|
if module_info["type"] == "library":
|
||||||
library_name = Path(module_info["library"]).stem.removeprefix("lib")
|
library_name = Path(module_info["library"]).stem.removeprefix("lib")
|
||||||
export_libraries = module_info.get("export-libraries", [])
|
export_libraries = module_info.get("export-libraries", [])
|
||||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
|
||||||
arcdir_prefab_include = f"prefab/modules/{module_name}/include"
|
arcdir_prefab_include = f"prefab/modules/{module_name}/include"
|
||||||
if "includes" in module_info:
|
if "includes" in module_info:
|
||||||
archive_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
|
aar_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
|
||||||
else:
|
else:
|
||||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
|
||||||
module_data_added = True
|
module_data_added = True
|
||||||
|
|
||||||
if not java_jars_added:
|
if not java_jars_added:
|
||||||
@@ -1025,21 +1094,28 @@ class Releaser:
|
|||||||
assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})"
|
assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})"
|
||||||
assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})"
|
assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})"
|
||||||
|
|
||||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
|
||||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
|
||||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
|
||||||
|
|
||||||
assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives"
|
assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives"
|
||||||
|
|
||||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
aar_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["aar-files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
||||||
|
|
||||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
|
||||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
|
aar_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
|
||||||
|
|
||||||
with Archiver(zip_path=aar_path) as archiver:
|
with Archiver(zip_path=aar_path) as archiver:
|
||||||
archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
|
aar_file_tree.add_to_archiver(archive_base="", archiver=archiver)
|
||||||
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
|
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
|
||||||
self.artifacts[f"android-aar"] = aar_path
|
|
||||||
|
android_devel_file_tree.add_file(NodeInArchive.from_fs(arcpath=aar_path.name, path=aar_path))
|
||||||
|
android_devel_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
||||||
|
with Archiver(zip_path=android_dist_path) as archiver:
|
||||||
|
android_devel_file_tree.add_to_archiver(archive_base="", archiver=archiver)
|
||||||
|
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
|
||||||
|
|
||||||
|
self.artifacts[f"android-aar"] = android_dist_path
|
||||||
|
|
||||||
def download_dependencies(self):
|
def download_dependencies(self):
|
||||||
shutil.rmtree(self.deps_path, ignore_errors=True)
|
shutil.rmtree(self.deps_path, ignore_errors=True)
|
||||||
@@ -1076,7 +1152,7 @@ class Releaser:
|
|||||||
assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
|
assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
|
||||||
if "android" in self.release_info:
|
if "android" in self.release_info:
|
||||||
android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
|
android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
|
||||||
assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
|
assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {android_matches}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig:
|
def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig:
|
||||||
@@ -1202,6 +1278,10 @@ class Releaser:
|
|||||||
platform_context = self.get_context(extra_context=arch_platform.extra_context())
|
platform_context = self.get_context(extra_context=arch_platform.extra_context())
|
||||||
|
|
||||||
build_type = "Release"
|
build_type = "Release"
|
||||||
|
extra_context = {
|
||||||
|
"ARCH": arch_platform.arch,
|
||||||
|
"PLATFORM": arch_platform.platform,
|
||||||
|
}
|
||||||
|
|
||||||
built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list)
|
built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list)
|
||||||
logger.info("CMake builds these files, to be included in the package: %s", built_paths)
|
logger.info("CMake builds these files, to be included in the package: %s", built_paths)
|
||||||
@@ -1252,7 +1332,7 @@ class Releaser:
|
|||||||
logger.info("Collecting files...")
|
logger.info("Collecting files...")
|
||||||
archive_file_tree = ArchiveFileTree()
|
archive_file_tree = ArchiveFileTree()
|
||||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time)
|
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time)
|
||||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
|
||||||
|
|
||||||
logger.info("Creating %s", zip_path)
|
logger.info("Creating %s", zip_path)
|
||||||
with Archiver(zip_path=zip_path) as archiver:
|
with Archiver(zip_path=zip_path) as archiver:
|
||||||
@@ -1316,7 +1396,7 @@ def main(argv=None) -> int:
|
|||||||
parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?")
|
parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?")
|
||||||
parser.set_defaults(loglevel=logging.INFO)
|
parser.set_defaults(loglevel=logging.INFO)
|
||||||
parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year")
|
parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year")
|
||||||
parser.add_argument('--android-api', type=int, dest="android_api", help="Android API version")
|
parser.add_argument('--android-api', dest="android_api", help="Android API version")
|
||||||
parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder")
|
parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder")
|
||||||
parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder")
|
parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder")
|
||||||
parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator")
|
parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator")
|
||||||
@@ -1443,14 +1523,27 @@ def main(argv=None) -> int:
|
|||||||
if args.android_api is None:
|
if args.android_api is None:
|
||||||
with section_printer.group("Detect Android APIS"):
|
with section_printer.group("Detect Android APIS"):
|
||||||
args.android_api = releaser._detect_android_api(android_home=args.android_home)
|
args.android_api = releaser._detect_android_api(android_home=args.android_home)
|
||||||
if args.android_api is None or not (Path(args.android_home) / f"platforms/android-{args.android_api}").is_dir():
|
else:
|
||||||
|
try:
|
||||||
|
android_api_ints = tuple(int(v) for v in args.android_api.split("."))
|
||||||
|
match len(android_api_ints):
|
||||||
|
case 1: android_api_name = f"android-{android_api_ints[0]}"
|
||||||
|
case 2: android_api_name = f"android-{android_api_ints[0]}-ext-{android_api_ints[1]}"
|
||||||
|
case _: raise ValueError
|
||||||
|
except ValueError:
|
||||||
|
logger.error("Invalid --android-api, must be a 'X' or 'X.Y' version")
|
||||||
|
args.android_api = AndroidApiVersion(ints=android_api_ints, name=android_api_name)
|
||||||
|
if args.android_api is None:
|
||||||
parser.error("Invalid --android-api, and/or could not be detected")
|
parser.error("Invalid --android-api, and/or could not be detected")
|
||||||
|
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
|
||||||
|
if not android_api_path.is_dir():
|
||||||
|
logger.warning(f"Android API directory does not exist ({android_api_path})")
|
||||||
with section_printer.group("Android arguments"):
|
with section_printer.group("Android arguments"):
|
||||||
print(f"android_home = {args.android_home}")
|
print(f"android_home = {args.android_home}")
|
||||||
print(f"android_ndk_home = {args.android_ndk_home}")
|
print(f"android_ndk_home = {args.android_ndk_home}")
|
||||||
print(f"android_api = {args.android_api}")
|
print(f"android_api = {args.android_api}")
|
||||||
releaser.create_android_archives(
|
releaser.create_android_archives(
|
||||||
android_api=args.android_api,
|
android_api=args.android_api.ints[0],
|
||||||
android_home=args.android_home,
|
android_home=args.android_home,
|
||||||
android_ndk_home=args.android_ndk_home,
|
android_ndk_home=args.android_ndk_home,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3508,7 +3508,7 @@ orig_CFLAGS="$CFLAGS"
|
|||||||
# See docs/release_checklist.md
|
# See docs/release_checklist.md
|
||||||
SDL_MAJOR_VERSION=2
|
SDL_MAJOR_VERSION=2
|
||||||
SDL_MINOR_VERSION=30
|
SDL_MINOR_VERSION=30
|
||||||
SDL_MICRO_VERSION=11
|
SDL_MICRO_VERSION=12
|
||||||
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
|
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
|
||||||
|
|
||||||
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
|
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ dnl Set various version strings - taken gratefully from the GTk sources
|
|||||||
# See docs/release_checklist.md
|
# See docs/release_checklist.md
|
||||||
SDL_MAJOR_VERSION=2
|
SDL_MAJOR_VERSION=2
|
||||||
SDL_MINOR_VERSION=30
|
SDL_MINOR_VERSION=30
|
||||||
SDL_MICRO_VERSION=11
|
SDL_MICRO_VERSION=12
|
||||||
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
|
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
|
||||||
|
|
||||||
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
|
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ typedef struct SDL_version
|
|||||||
*/
|
*/
|
||||||
#define SDL_MAJOR_VERSION 2
|
#define SDL_MAJOR_VERSION 2
|
||||||
#define SDL_MINOR_VERSION 30
|
#define SDL_MINOR_VERSION 30
|
||||||
#define SDL_PATCHLEVEL 11
|
#define SDL_PATCHLEVEL 12
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Macro to determine SDL version program was compiled against.
|
* Macro to determine SDL version program was compiled against.
|
||||||
|
|||||||
@@ -5,18 +5,18 @@ CROSS_PATH := /usr/local
|
|||||||
ARCHITECTURES := i686-w64-mingw32 x86_64-w64-mingw32
|
ARCHITECTURES := i686-w64-mingw32 x86_64-w64-mingw32
|
||||||
|
|
||||||
all install:
|
all install:
|
||||||
@echo "Type \"make native\" to install 32-bit to /usr"
|
@echo "Type \"$(MAKE) native\" to install 32-bit to /usr"
|
||||||
@echo "Type \"make cross\" to install 32-bit and 64-bit to $(CROSS_PATH)"
|
@echo "Type \"$(MAKE) cross\" to install 32-bit and 64-bit to $(CROSS_PATH)"
|
||||||
|
|
||||||
native:
|
native:
|
||||||
make install-package arch=i686-w64-mingw32 prefix=/usr
|
$(MAKE) install-package arch=i686-w64-mingw32 prefix=/usr
|
||||||
|
|
||||||
cross:
|
cross:
|
||||||
mkdir -p $(CROSS_PATH)/cmake
|
mkdir -p $(CROSS_PATH)/cmake
|
||||||
cp -rv cmake/* $(CROSS_PATH)/cmake
|
cp -rv cmake/* $(CROSS_PATH)/cmake
|
||||||
for arch in $(ARCHITECTURES); do \
|
for arch in $(ARCHITECTURES); do \
|
||||||
mkdir -p $(CROSS_PATH)/$$arch; \
|
mkdir -p $(CROSS_PATH)/$$arch; \
|
||||||
make install-package arch=$$arch prefix=$(CROSS_PATH)/$$arch; \
|
$(MAKE) install-package arch=$$arch prefix=$(CROSS_PATH)/$$arch; \
|
||||||
done
|
done
|
||||||
|
|
||||||
install-package:
|
install-package:
|
||||||
@@ -30,7 +30,7 @@ install-package:
|
|||||||
-e "s|^set[(]libdir \".*|set(libdir \"$(prefix)/lib\")|" <$(arch)/lib/cmake/SDL2/sdl2-config.cmake >$(prefix)/lib/cmake/SDL2/sdl2-config.cmake; \
|
-e "s|^set[(]libdir \".*|set(libdir \"$(prefix)/lib\")|" <$(arch)/lib/cmake/SDL2/sdl2-config.cmake >$(prefix)/lib/cmake/SDL2/sdl2-config.cmake; \
|
||||||
sed -e "s|^prefix=.*|prefix=$(prefix)|" \
|
sed -e "s|^prefix=.*|prefix=$(prefix)|" \
|
||||||
-e "s|^includedir=.*|includedir=$(prefix)/include|" \
|
-e "s|^includedir=.*|includedir=$(prefix)/include|" \
|
||||||
-e "s|^libdir=.*|prefix=$(prefix)/lib|" <$(arch)/lib/pkgconfig/sdl2.pc >$(prefix)/lib/pkgconfig/sdl2.pc; \
|
-e "s|^libdir=.*|libdir=$(prefix)/lib|" <$(arch)/lib/pkgconfig/sdl2.pc >$(prefix)/lib/pkgconfig/sdl2.pc; \
|
||||||
else \
|
else \
|
||||||
echo "*** ERROR: $(arch) or $(prefix) does not exist!"; \
|
echo "*** ERROR: $(arch) or $(prefix) does not exist!"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
|
|||||||
@@ -673,7 +673,21 @@ static OSStatus default_device_changed(AudioObjectID inObjectID, UInt32 inNumber
|
|||||||
#if DEBUG_COREAUDIO
|
#if DEBUG_COREAUDIO
|
||||||
printf("COREAUDIO: default device changed for SDL audio device %p!\n", this);
|
printf("COREAUDIO: default device changed for SDL audio device %p!\n", this);
|
||||||
#endif
|
#endif
|
||||||
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
|
|
||||||
|
/* due to a bug (?) in CoreAudio, this seems able to fire for a device pointer that's already closed, so check our list to make sure
|
||||||
|
the pointer is still valid before touching it. https://github.com/libsdl-org/SDL/issues/10432 */
|
||||||
|
if (open_devices) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < num_open_devices; i++) {
|
||||||
|
SDL_AudioDevice *device = open_devices[i];
|
||||||
|
if (device == this) {
|
||||||
|
if (this->hidden) {
|
||||||
|
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
|
||||||
|
}
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -880,14 +894,25 @@ static int prepare_audioqueue(_THIS)
|
|||||||
// L R C LFE Ls Rs
|
// L R C LFE Ls Rs
|
||||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_12;
|
layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_12;
|
||||||
break;
|
break;
|
||||||
|
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || \
|
||||||
|
(defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101500)
|
||||||
case 7:
|
case 7:
|
||||||
// L R C LFE Cs Ls Rs
|
// L R C LFE Cs Ls Rs
|
||||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_6_1;
|
if (@available(macOS 10.15, iOS 13, *)) {
|
||||||
|
layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_6_1;
|
||||||
|
} else {
|
||||||
|
return SDL_SetError("Unsupported audio channels");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// L R C LFE Rls Rrs Ls Rs
|
// L R C LFE Rls Rrs Ls Rs
|
||||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_7_1;
|
if (@available(macOS 10.15, iOS 13, *)) {
|
||||||
|
layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_7_1;
|
||||||
|
} else {
|
||||||
|
return SDL_SetError("Unsupported audio channels");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return SDL_SetError("Unsupported audio channels");
|
return SDL_SetError("Unsupported audio channels");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,14 +122,14 @@ static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *
|
|||||||
switch (*hint) {
|
switch (*hint) {
|
||||||
default:
|
default:
|
||||||
case '0':
|
case '0':
|
||||||
mouse->vita_touch_mouse_device = 0;
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
mouse->vita_touch_mouse_device = 1;
|
mouse->vita_touch_mouse_device = 1;
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '1':
|
||||||
mouse->vita_touch_mouse_device = 2;
|
mouse->vita_touch_mouse_device = 2;
|
||||||
break;
|
break;
|
||||||
|
case '2':
|
||||||
|
mouse->vita_touch_mouse_device = 3;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
|
|||||||
/* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */
|
/* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */
|
||||||
{
|
{
|
||||||
#if defined(__vita__)
|
#if defined(__vita__)
|
||||||
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2))) {
|
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 3))) {
|
||||||
#else
|
#else
|
||||||
if (mouse->touch_mouse_events) {
|
if (mouse->touch_mouse_events) {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ static SDL_bool IsRegularFileOrPipe(FILE *f)
|
|||||||
!((st.st_mode & _S_IFMT) == _S_IFREG || (st.st_mode & _S_IFMT) == _S_IFIFO)) {
|
!((st.st_mode & _S_IFMT) == _S_IFREG || (st.st_mode & _S_IFMT) == _S_IFIFO)) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
#else
|
#elif !defined __EMSCRIPTEN__
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fileno(f), &st) < 0 || !(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) {
|
if (fstat(fileno(f), &st) < 0 || !(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
|
|||||||
@@ -878,7 +878,7 @@ static int SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect *src)
|
|||||||
|
|
||||||
/* Header */
|
/* Header */
|
||||||
dest->type = FF_RUMBLE;
|
dest->type = FF_RUMBLE;
|
||||||
dest->direction = 0;
|
dest->direction = 0x4000;
|
||||||
|
|
||||||
/* Replay */
|
/* Replay */
|
||||||
dest->replay.length = (leftright->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(leftright->length);
|
dest->replay.length = (leftright->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(leftright->length);
|
||||||
|
|||||||
@@ -2126,6 +2126,18 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
|
|||||||
|
|
||||||
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL);
|
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL);
|
||||||
|
|
||||||
|
#ifdef __WIN32__
|
||||||
|
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE) &&
|
||||||
|
SDL_GetHintBoolean("STEAM_COMPAT_PROTON", SDL_FALSE)) {
|
||||||
|
/* We are launched by Steam and running under Proton
|
||||||
|
* We can't tell whether this controller is a Steam Virtual Gamepad,
|
||||||
|
* so assume that Proton is doing the appropriate filtering of controllers
|
||||||
|
* and anything we see here is fine to use.
|
||||||
|
*/
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
#endif // __WIN32__
|
||||||
|
|
||||||
if (SDL_IsJoystickSteamVirtualGamepad(vendor, product, version)) {
|
if (SDL_IsJoystickSteamVirtualGamepad(vendor, product, version)) {
|
||||||
return !SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE);
|
return !SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ static const char *s_ControllerMappings[] = {
|
|||||||
"03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
"030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
"030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
|
"03000000c82d00001b30000000000000,8BitDo Ultimate 2C Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a2,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,", /* Bluetooth */
|
||||||
"03000000c82d00001130000000000000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
"03000000c82d00001130000000000000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||||
"03000000c82d00001330000000000000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
"03000000c82d00001330000000000000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||||
"03000000c82d00001890000000000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00001890000000000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
@@ -397,6 +398,7 @@ static const char *s_ControllerMappings[] = {
|
|||||||
"03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
"03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
"03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
|
"03000000c82d00001b30000001000000,8BitDo Ultimate 2C Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Bluetooth */
|
||||||
"03000000c82d00001130000000020000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
"03000000c82d00001130000000020000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||||
"03000000c82d00001330000000020000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
"03000000c82d00001330000000020000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||||
"03000000c82d00001890000001000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00001890000001000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
@@ -567,6 +569,7 @@ static const char *s_ControllerMappings[] = {
|
|||||||
"030000003512000020ab000010010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"030000003512000020ab000010010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
"05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
"05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
|
"05000000c82d00001b30000001000000,8BitDo Ultimate 2C Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Bluetooth */
|
||||||
"03000000c82d00001130000011010000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
"03000000c82d00001130000011010000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||||
"03000000c82d00001330000011010000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
"03000000c82d00001330000011010000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||||
"03000000c82d00001890000011010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
"03000000c82d00001890000011010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ static SDL_bool HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device)
|
|||||||
j = -1;
|
j = -1;
|
||||||
for (i = 0; i < 12; i += 2) {
|
for (i = 0; i < 12; i += 2) {
|
||||||
j += 1;
|
j += 1;
|
||||||
SDL_memcpy(&serial[j], &device->serial[i], 2);
|
SDL_memmove(&serial[j], &device->serial[i], 2);
|
||||||
j += 2;
|
j += 2;
|
||||||
serial[j] = '-';
|
serial[j] = '-';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
|
|||||||
j = -1;
|
j = -1;
|
||||||
for (i = 0; i < 12; i += 2) {
|
for (i = 0; i < 12; i += 2) {
|
||||||
j += 1;
|
j += 1;
|
||||||
SDL_memcpy(&serial[j], &device->serial[i], 2);
|
SDL_memmove(&serial[j], &device->serial[i], 2);
|
||||||
j += 2;
|
j += 2;
|
||||||
serial[j] = '-';
|
serial[j] = '-';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ extern SDL_bool SDL_XINPUT_Enabled(void);
|
|||||||
extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version);
|
extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version);
|
||||||
|
|
||||||
|
|
||||||
static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product, const char* name)
|
||||||
{
|
{
|
||||||
#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT)
|
#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT)
|
||||||
PRAWINPUTDEVICELIST raw_devices = NULL;
|
PRAWINPUTDEVICELIST raw_devices = NULL;
|
||||||
@@ -126,6 +126,13 @@ static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
|||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sometimes we'll get a Windows.Gaming.Input callback before the raw input device is even in the list,
|
||||||
|
* so try to do some checks up front to catch these cases. */
|
||||||
|
if (SDL_IsJoystickXboxOne(vendor, product) ||
|
||||||
|
(name && SDL_strncmp(name, "Xbox ", 5) == 0)) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
||||||
if ((GetRawInputDeviceList(NULL, &raw_device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!raw_device_count)) {
|
if ((GetRawInputDeviceList(NULL, &raw_device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!raw_device_count)) {
|
||||||
return SDL_FALSE; /* oh well. */
|
return SDL_FALSE; /* oh well. */
|
||||||
@@ -508,7 +515,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
|||||||
ignore_joystick = SDL_TRUE;
|
ignore_joystick = SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignore_joystick && SDL_IsXInputDevice(vendor, product)) {
|
if (!ignore_joystick && SDL_IsXInputDevice(vendor, product, name)) {
|
||||||
ignore_joystick = SDL_TRUE;
|
ignore_joystick = SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,30,11,0
|
FILEVERSION 2,30,12,0
|
||||||
PRODUCTVERSION 2,30,11,0
|
PRODUCTVERSION 2,30,12,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
FILEFLAGS 0x0L
|
FILEFLAGS 0x0L
|
||||||
FILEOS 0x40004L
|
FILEOS 0x40004L
|
||||||
@@ -23,12 +23,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "\0"
|
VALUE "CompanyName", "\0"
|
||||||
VALUE "FileDescription", "SDL\0"
|
VALUE "FileDescription", "SDL\0"
|
||||||
VALUE "FileVersion", "2, 30, 11, 0\0"
|
VALUE "FileVersion", "2, 30, 12, 0\0"
|
||||||
VALUE "InternalName", "SDL\0"
|
VALUE "InternalName", "SDL\0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
|
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
|
||||||
VALUE "OriginalFilename", "SDL2.dll\0"
|
VALUE "OriginalFilename", "SDL2.dll\0"
|
||||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||||
VALUE "ProductVersion", "2, 30, 11, 0\0"
|
VALUE "ProductVersion", "2, 30, 12, 0\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@@ -688,7 +688,9 @@ void SDL_DelVideoDisplay(int index)
|
|||||||
SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_DISCONNECTED, 0);
|
SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_DISCONNECTED, 0);
|
||||||
|
|
||||||
SDL_free(_this->displays[index].driverdata);
|
SDL_free(_this->displays[index].driverdata);
|
||||||
|
_this->displays[index].driverdata = NULL;
|
||||||
SDL_free(_this->displays[index].name);
|
SDL_free(_this->displays[index].name);
|
||||||
|
_this->displays[index].name = NULL;
|
||||||
if (index < (_this->num_displays - 1)) {
|
if (index < (_this->num_displays - 1)) {
|
||||||
SDL_memmove(&_this->displays[index], &_this->displays[index + 1], (_this->num_displays - index - 1) * sizeof(_this->displays[index]));
|
SDL_memmove(&_this->displays[index], &_this->displays[index + 1], (_this->num_displays - index - 1) * sizeof(_this->displays[index]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
NSWindow *nswindow;
|
NSWindow *nswindow;
|
||||||
}
|
}
|
||||||
- (id)initWithParentWindow:(SDL_Window *)window;
|
- (id)initWithParentWindow:(SDL_Window *)window;
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
|
||||||
|
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
|
||||||
|
#endif
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SDLMessageBoxPresenter
|
@implementation SDLMessageBoxPresenter
|
||||||
@@ -56,16 +59,32 @@
|
|||||||
- (void)showAlert:(NSAlert*)alert
|
- (void)showAlert:(NSAlert*)alert
|
||||||
{
|
{
|
||||||
if (nswindow) {
|
if (nswindow) {
|
||||||
[alert beginSheetModalForWindow:nswindow
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
|
||||||
|
if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
|
||||||
|
[alert beginSheetModalForWindow:nswindow
|
||||||
completionHandler:^(NSModalResponse returnCode) {
|
completionHandler:^(NSModalResponse returnCode) {
|
||||||
[NSApp stopModalWithCode:returnCode];
|
[NSApp stopModalWithCode:returnCode];
|
||||||
}];
|
}];
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
|
||||||
|
[alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
clicked = [NSApp runModalForWindow:nswindow];
|
clicked = [NSApp runModalForWindow:nswindow];
|
||||||
nswindow = nil;
|
nswindow = nil;
|
||||||
} else {
|
} else {
|
||||||
clicked = [alert runModal];
|
clicked = [alert runModal];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
|
||||||
|
- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
|
||||||
|
{
|
||||||
|
[NSApp stopModalWithCode:returnCode];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ typedef enum
|
|||||||
/* Window delegate functionality */
|
/* Window delegate functionality */
|
||||||
-(BOOL) windowShouldClose:(id) sender;
|
-(BOOL) windowShouldClose:(id) sender;
|
||||||
-(void) windowDidExpose:(NSNotification *) aNotification;
|
-(void) windowDidExpose:(NSNotification *) aNotification;
|
||||||
|
-(void) onLiveResizeTimerFire:(id) sender;
|
||||||
-(void) windowWillStartLiveResize:(NSNotification *)aNotification;
|
-(void) windowWillStartLiveResize:(NSNotification *)aNotification;
|
||||||
-(void) windowDidEndLiveResize:(NSNotification *)aNotification;
|
-(void) windowDidEndLiveResize:(NSNotification *)aNotification;
|
||||||
-(void) windowDidMove:(NSNotification *) aNotification;
|
-(void) windowDidMove:(NSNotification *) aNotification;
|
||||||
|
|||||||
@@ -743,16 +743,26 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
|
|||||||
SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
|
SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)onLiveResizeTimerFire:(id)sender
|
||||||
|
{
|
||||||
|
SDL_OnWindowLiveResizeUpdate(_data.window);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)windowWillStartLiveResize:(NSNotification *)aNotification
|
- (void)windowWillStartLiveResize:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
// We'll try to maintain 60 FPS during live resizing
|
// We'll try to maintain 60 FPS during live resizing
|
||||||
const NSTimeInterval interval = 1.0 / 60.0;
|
const NSTimeInterval interval = 1.0 / 60.0;
|
||||||
|
|
||||||
|
NSMethodSignature *invocationSig = [Cocoa_WindowListener
|
||||||
|
instanceMethodSignatureForSelector:@selector(onLiveResizeTimerFire:)];
|
||||||
|
NSInvocation *invocation = [NSInvocation
|
||||||
|
invocationWithMethodSignature:invocationSig];
|
||||||
|
[invocation setTarget:self];
|
||||||
|
[invocation setSelector:@selector(onLiveResizeTimerFire:)];
|
||||||
|
|
||||||
liveResizeTimer = [NSTimer scheduledTimerWithTimeInterval:interval
|
liveResizeTimer = [NSTimer scheduledTimerWithTimeInterval:interval
|
||||||
repeats:TRUE
|
invocation:invocation
|
||||||
block:^(NSTimer *unusedTimer)
|
repeats:TRUE];
|
||||||
{
|
|
||||||
SDL_OnWindowLiveResizeUpdate(_data.window);
|
|
||||||
}];
|
|
||||||
|
|
||||||
[[NSRunLoop currentRunLoop] addTimer:liveResizeTimer forMode:NSRunLoopCommonModes];
|
[[NSRunLoop currentRunLoop] addTimer:liveResizeTimer forMode:NSRunLoopCommonModes];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -794,6 +794,20 @@ static EM_BOOL Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent
|
|||||||
return preventDefault;
|
return preventDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_bool IsFunctionKey(SDL_Scancode scancode)
|
||||||
|
{
|
||||||
|
if (scancode >= SDL_SCANCODE_F1 && scancode <= SDL_SCANCODE_F12) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
if (scancode >= SDL_SCANCODE_F13 && scancode <= SDL_SCANCODE_F24) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a great tool to see web keyboard events live:
|
||||||
|
* https://w3c.github.io/uievents/tools/key-event-viewer.html
|
||||||
|
*/
|
||||||
static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
|
static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
|
||||||
{
|
{
|
||||||
const SDL_Keycode keycode = Emscripten_MapKeyCode(keyEvent);
|
const SDL_Keycode keycode = Emscripten_MapKeyCode(keyEvent);
|
||||||
@@ -823,7 +837,7 @@ static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent
|
|||||||
(scancode == SDL_SCANCODE_UP) ||
|
(scancode == SDL_SCANCODE_UP) ||
|
||||||
(scancode == SDL_SCANCODE_RIGHT) ||
|
(scancode == SDL_SCANCODE_RIGHT) ||
|
||||||
(scancode == SDL_SCANCODE_DOWN) ||
|
(scancode == SDL_SCANCODE_DOWN) ||
|
||||||
((scancode >= SDL_SCANCODE_F1) && (scancode <= SDL_SCANCODE_F15)) ||
|
IsFunctionKey(scancode) ||
|
||||||
keyEvent->ctrlKey) {
|
keyEvent->ctrlKey) {
|
||||||
is_nav_key = SDL_TRUE;
|
is_nav_key = SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ void UIKit_DelDisplay(UIScreen *uiscreen)
|
|||||||
|
|
||||||
if (data && data.uiscreen == uiscreen) {
|
if (data && data.uiscreen == uiscreen) {
|
||||||
CFRelease(SDL_GetDisplayDriverData(i));
|
CFRelease(SDL_GetDisplayDriverData(i));
|
||||||
|
SDL_GetDisplay(i)->driverdata = NULL;
|
||||||
SDL_DelVideoDisplay(i);
|
SDL_DelVideoDisplay(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2147,6 +2147,18 @@ void Wayland_add_primary_selection_device_manager(SDL_VideoData *d, uint32_t id,
|
|||||||
|
|
||||||
void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version)
|
void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_FCITX
|
||||||
|
const char *im_module = SDL_getenv("SDL_IM_MODULE");
|
||||||
|
if (im_module && SDL_strcmp(im_module, "fcitx") == 0) {
|
||||||
|
/* Override the Wayland text-input protocol when Fcitx is enabled, like how GTK_IM_MODULE does.
|
||||||
|
*
|
||||||
|
* The Fcitx wiki discourages enabling it under Wayland via SDL_IM_MODULE, so its presence must
|
||||||
|
* be intentional, and this workaround is needed for fixing key repeat detection.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
d->text_input_manager = wl_registry_bind(d->registry, id, &zwp_text_input_manager_v3_interface, 1);
|
d->text_input_manager = wl_registry_bind(d->registry, id, &zwp_text_input_manager_v3_interface, 1);
|
||||||
|
|
||||||
if (d->input) {
|
if (d->input) {
|
||||||
|
|||||||
@@ -837,7 +837,7 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
|||||||
} else if (SDL_strcmp(interface, "wl_seat") == 0) {
|
} else if (SDL_strcmp(interface, "wl_seat") == 0) {
|
||||||
Wayland_display_add_input(d, id, version);
|
Wayland_display_add_input(d, id, version);
|
||||||
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
|
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
|
||||||
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3));
|
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 5));
|
||||||
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
|
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
|
||||||
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
|
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
|
||||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||||
|
|||||||
@@ -536,6 +536,13 @@ static void handle_configure_xdg_toplevel(void *data,
|
|||||||
*/
|
*/
|
||||||
width = wind->floating_width;
|
width = wind->floating_width;
|
||||||
height = wind->floating_height;
|
height = wind->floating_height;
|
||||||
|
|
||||||
|
/* Clamp resizable windows to the toplevel bounds when mapping, if any were sent. */
|
||||||
|
if ((window->flags & (SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE)) &&
|
||||||
|
wind->toplevel_bounds_width && wind->toplevel_bounds_height) {
|
||||||
|
width = SDL_min(width, wind->toplevel_bounds_width);
|
||||||
|
height = SDL_min(height, wind->toplevel_bounds_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xdg_toplevel spec states that this is a suggestion.
|
/* xdg_toplevel spec states that this is a suggestion.
|
||||||
@@ -612,9 +619,28 @@ static void handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_tople
|
|||||||
SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_xdg_toplevel_configure_bounds(void *data,
|
||||||
|
struct xdg_toplevel *xdg_toplevel,
|
||||||
|
int32_t width,
|
||||||
|
int32_t height)
|
||||||
|
{
|
||||||
|
SDL_WindowData *window = (SDL_WindowData *)data;
|
||||||
|
window->toplevel_bounds_width = width;
|
||||||
|
window->toplevel_bounds_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_xdg_toplevel_wm_capabilities(void *data,
|
||||||
|
struct xdg_toplevel *xdg_toplevel,
|
||||||
|
struct wl_array *capabilities)
|
||||||
|
{
|
||||||
|
/* NOP */
|
||||||
|
}
|
||||||
|
|
||||||
static const struct xdg_toplevel_listener toplevel_listener_xdg = {
|
static const struct xdg_toplevel_listener toplevel_listener_xdg = {
|
||||||
handle_configure_xdg_toplevel,
|
handle_configure_xdg_toplevel,
|
||||||
handle_close_xdg_toplevel
|
handle_close_xdg_toplevel,
|
||||||
|
handle_xdg_toplevel_configure_bounds,
|
||||||
|
handle_xdg_toplevel_wm_capabilities
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_configure_xdg_popup(void *data,
|
static void handle_configure_xdg_popup(void *data,
|
||||||
@@ -1338,6 +1364,12 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (c->shell.xdg) {
|
if (c->shell.xdg) {
|
||||||
|
/* Create the window decorations */
|
||||||
|
if (data->shell_surface_type != WAYLAND_SURFACE_XDG_POPUP && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
|
||||||
|
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
|
||||||
|
zxdg_toplevel_decoration_v1_add_listener(data->server_decoration, &decoration_listener, window);
|
||||||
|
}
|
||||||
|
|
||||||
/* Unlike libdecor we need to call this explicitly to prevent a deadlock.
|
/* Unlike libdecor we need to call this explicitly to prevent a deadlock.
|
||||||
* libdecor will call this as part of their configure event!
|
* libdecor will call this as part of their configure event!
|
||||||
* -flibit
|
* -flibit
|
||||||
@@ -1349,14 +1381,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||||||
WAYLAND_wl_display_dispatch(c->display);
|
WAYLAND_wl_display_dispatch(c->display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the window decorations */
|
|
||||||
if (data->shell_surface_type != WAYLAND_SURFACE_XDG_POPUP && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
|
|
||||||
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
|
|
||||||
zxdg_toplevel_decoration_v1_add_listener(data->server_decoration,
|
|
||||||
&decoration_listener,
|
|
||||||
window);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* Nothing to see here, just commit. */
|
/* Nothing to see here, just commit. */
|
||||||
wl_surface_commit(data->surface);
|
wl_surface_commit(data->surface);
|
||||||
|
|||||||
@@ -110,13 +110,15 @@ typedef struct
|
|||||||
int window_width, window_height;
|
int window_width, window_height;
|
||||||
int system_min_required_width;
|
int system_min_required_width;
|
||||||
int system_min_required_height;
|
int system_min_required_height;
|
||||||
|
int toplevel_bounds_width;
|
||||||
|
int toplevel_bounds_height;
|
||||||
SDL_bool needs_resize_event;
|
SDL_bool needs_resize_event;
|
||||||
SDL_bool floating_resize_pending;
|
SDL_bool floating_resize_pending;
|
||||||
SDL_bool was_floating;
|
SDL_bool was_floating;
|
||||||
SDL_bool is_fullscreen;
|
SDL_bool is_fullscreen;
|
||||||
SDL_bool in_fullscreen_transition;
|
SDL_bool in_fullscreen_transition;
|
||||||
Uint32 fullscreen_flags;
|
Uint32 fullscreen_flags;
|
||||||
SDL_bool double_buffer;
|
SDL_bool double_buffer;
|
||||||
} SDL_WindowData;
|
} SDL_WindowData;
|
||||||
|
|
||||||
extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
|
extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
|
||||||
|
|||||||
+210
-67
@@ -29,7 +29,7 @@
|
|||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
<interface name="xdg_wm_base" version="3">
|
<interface name="xdg_wm_base" version="6">
|
||||||
<description summary="create desktop-style surfaces">
|
<description summary="create desktop-style surfaces">
|
||||||
The xdg_wm_base interface is exposed as a global object enabling clients
|
The xdg_wm_base interface is exposed as a global object enabling clients
|
||||||
to turn their wl_surfaces into windows in a desktop environment. It
|
to turn their wl_surfaces into windows in a desktop environment. It
|
||||||
@@ -50,6 +50,8 @@
|
|||||||
summary="the client provided an invalid surface state"/>
|
summary="the client provided an invalid surface state"/>
|
||||||
<entry name="invalid_positioner" value="5"
|
<entry name="invalid_positioner" value="5"
|
||||||
summary="the client provided an invalid positioner"/>
|
summary="the client provided an invalid positioner"/>
|
||||||
|
<entry name="unresponsive" value="6"
|
||||||
|
summary="the client didn’t respond to a ping event in time"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
<request name="destroy" type="destructor">
|
||||||
@@ -58,7 +60,7 @@
|
|||||||
|
|
||||||
Destroying a bound xdg_wm_base object while there are surfaces
|
Destroying a bound xdg_wm_base object while there are surfaces
|
||||||
still alive created by this xdg_wm_base object instance is illegal
|
still alive created by this xdg_wm_base object instance is illegal
|
||||||
and will result in a protocol error.
|
and will result in a defunct_surfaces error.
|
||||||
</description>
|
</description>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
@@ -75,7 +77,9 @@
|
|||||||
<description summary="create a shell surface from a surface">
|
<description summary="create a shell surface from a surface">
|
||||||
This creates an xdg_surface for the given surface. While xdg_surface
|
This creates an xdg_surface for the given surface. While xdg_surface
|
||||||
itself is not a role, the corresponding surface may only be assigned
|
itself is not a role, the corresponding surface may only be assigned
|
||||||
a role extending xdg_surface, such as xdg_toplevel or xdg_popup.
|
a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is
|
||||||
|
illegal to create an xdg_surface for a wl_surface which already has an
|
||||||
|
assigned role and this will result in a role error.
|
||||||
|
|
||||||
This creates an xdg_surface for the given surface. An xdg_surface is
|
This creates an xdg_surface for the given surface. An xdg_surface is
|
||||||
used as basis to define a role to a given surface, such as xdg_toplevel
|
used as basis to define a role to a given surface, such as xdg_toplevel
|
||||||
@@ -92,7 +96,8 @@
|
|||||||
<request name="pong">
|
<request name="pong">
|
||||||
<description summary="respond to a ping event">
|
<description summary="respond to a ping event">
|
||||||
A client must respond to a ping event with a pong request or
|
A client must respond to a ping event with a pong request or
|
||||||
the client may be deemed unresponsive. See xdg_wm_base.ping.
|
the client may be deemed unresponsive. See xdg_wm_base.ping
|
||||||
|
and xdg_wm_base.error.unresponsive.
|
||||||
</description>
|
</description>
|
||||||
<arg name="serial" type="uint" summary="serial of the ping event"/>
|
<arg name="serial" type="uint" summary="serial of the ping event"/>
|
||||||
</request>
|
</request>
|
||||||
@@ -106,7 +111,9 @@
|
|||||||
Compositors can use this to determine if the client is still
|
Compositors can use this to determine if the client is still
|
||||||
alive. It's unspecified what will happen if the client doesn't
|
alive. It's unspecified what will happen if the client doesn't
|
||||||
respond to the ping request, or in what timeframe. Clients should
|
respond to the ping request, or in what timeframe. Clients should
|
||||||
try to respond in a reasonable amount of time.
|
try to respond in a reasonable amount of time. The “unresponsive”
|
||||||
|
error is provided for compositors that wish to disconnect unresponsive
|
||||||
|
clients.
|
||||||
|
|
||||||
A compositor is free to ping in any way it wants, but a client must
|
A compositor is free to ping in any way it wants, but a client must
|
||||||
always respond to any xdg_wm_base object it created.
|
always respond to any xdg_wm_base object it created.
|
||||||
@@ -115,7 +122,7 @@
|
|||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="xdg_positioner" version="3">
|
<interface name="xdg_positioner" version="6">
|
||||||
<description summary="child surface positioner">
|
<description summary="child surface positioner">
|
||||||
The xdg_positioner provides a collection of rules for the placement of a
|
The xdg_positioner provides a collection of rules for the placement of a
|
||||||
child surface relative to a parent surface. Rules can be defined to ensure
|
child surface relative to a parent surface. Rules can be defined to ensure
|
||||||
@@ -135,7 +142,7 @@
|
|||||||
For an xdg_positioner object to be considered complete, it must have a
|
For an xdg_positioner object to be considered complete, it must have a
|
||||||
non-zero size set by set_size, and a non-zero anchor rectangle set by
|
non-zero size set by set_size, and a non-zero anchor rectangle set by
|
||||||
set_anchor_rect. Passing an incomplete xdg_positioner object when
|
set_anchor_rect. Passing an incomplete xdg_positioner object when
|
||||||
positioning a surface raises an error.
|
positioning a surface raises an invalid_positioner error.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<enum name="error">
|
<enum name="error">
|
||||||
@@ -223,7 +230,8 @@
|
|||||||
specified (e.g. 'bottom_right' or 'top_left'), then the child surface
|
specified (e.g. 'bottom_right' or 'top_left'), then the child surface
|
||||||
will be placed towards the specified gravity; otherwise, the child
|
will be placed towards the specified gravity; otherwise, the child
|
||||||
surface will be centered over the anchor point on any axis that had no
|
surface will be centered over the anchor point on any axis that had no
|
||||||
gravity specified.
|
gravity specified. If the gravity is not in the ‘gravity’ enum, an
|
||||||
|
invalid_input error is raised.
|
||||||
</description>
|
</description>
|
||||||
<arg name="gravity" type="uint" enum="gravity"
|
<arg name="gravity" type="uint" enum="gravity"
|
||||||
summary="gravity direction"/>
|
summary="gravity direction"/>
|
||||||
@@ -336,7 +344,7 @@
|
|||||||
|
|
||||||
The default adjustment is none.
|
The default adjustment is none.
|
||||||
</description>
|
</description>
|
||||||
<arg name="constraint_adjustment" type="uint"
|
<arg name="constraint_adjustment" type="uint" enum="constraint_adjustment"
|
||||||
summary="bit mask of constraint adjustments"/>
|
summary="bit mask of constraint adjustments"/>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
@@ -389,7 +397,7 @@
|
|||||||
|
|
||||||
<request name="set_parent_configure" since="3">
|
<request name="set_parent_configure" since="3">
|
||||||
<description summary="set parent configure this is a response to">
|
<description summary="set parent configure this is a response to">
|
||||||
Set the serial of a xdg_surface.configure event this positioner will be
|
Set the serial of an xdg_surface.configure event this positioner will be
|
||||||
used in response to. The compositor may use this information together
|
used in response to. The compositor may use this information together
|
||||||
with set_parent_size to determine what future state the popup should be
|
with set_parent_size to determine what future state the popup should be
|
||||||
constrained using.
|
constrained using.
|
||||||
@@ -399,7 +407,7 @@
|
|||||||
</request>
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="xdg_surface" version="3">
|
<interface name="xdg_surface" version="6">
|
||||||
<description summary="desktop user interface surface base interface">
|
<description summary="desktop user interface surface base interface">
|
||||||
An interface that may be implemented by a wl_surface, for
|
An interface that may be implemented by a wl_surface, for
|
||||||
implementations that provide a desktop-style user interface.
|
implementations that provide a desktop-style user interface.
|
||||||
@@ -426,6 +434,14 @@
|
|||||||
manipulate a buffer prior to the first xdg_surface.configure call must
|
manipulate a buffer prior to the first xdg_surface.configure call must
|
||||||
also be treated as errors.
|
also be treated as errors.
|
||||||
|
|
||||||
|
After creating a role-specific object and setting it up (e.g. by sending
|
||||||
|
the title, app ID, size constraints, parent, etc), the client must
|
||||||
|
perform an initial commit without any buffer attached. The compositor
|
||||||
|
will reply with initial wl_surface state such as
|
||||||
|
wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
|
||||||
|
event. The client must acknowledge it and is then allowed to attach a
|
||||||
|
buffer to map the surface.
|
||||||
|
|
||||||
Mapping an xdg_surface-based role surface is defined as making it
|
Mapping an xdg_surface-based role surface is defined as making it
|
||||||
possible for the surface to be shown by the compositor. Note that
|
possible for the surface to be shown by the compositor. Note that
|
||||||
a mapped surface is not guaranteed to be visible once it is mapped.
|
a mapped surface is not guaranteed to be visible once it is mapped.
|
||||||
@@ -439,19 +455,30 @@
|
|||||||
|
|
||||||
A newly-unmapped surface is considered to have met condition (1) out
|
A newly-unmapped surface is considered to have met condition (1) out
|
||||||
of the 3 required conditions for mapping a surface if its role surface
|
of the 3 required conditions for mapping a surface if its role surface
|
||||||
has not been destroyed.
|
has not been destroyed, i.e. the client must perform the initial commit
|
||||||
|
again before attaching a buffer.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<enum name="error">
|
<enum name="error">
|
||||||
<entry name="not_constructed" value="1"/>
|
<entry name="not_constructed" value="1"
|
||||||
<entry name="already_constructed" value="2"/>
|
summary="Surface was not fully constructed"/>
|
||||||
<entry name="unconfigured_buffer" value="3"/>
|
<entry name="already_constructed" value="2"
|
||||||
|
summary="Surface was already constructed"/>
|
||||||
|
<entry name="unconfigured_buffer" value="3"
|
||||||
|
summary="Attaching a buffer to an unconfigured surface"/>
|
||||||
|
<entry name="invalid_serial" value="4"
|
||||||
|
summary="Invalid serial number when acking a configure event"/>
|
||||||
|
<entry name="invalid_size" value="5"
|
||||||
|
summary="Width or height was zero or negative"/>
|
||||||
|
<entry name="defunct_role_object" value="6"
|
||||||
|
summary="Surface was destroyed before its role object"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
<request name="destroy" type="destructor">
|
||||||
<description summary="destroy the xdg_surface">
|
<description summary="destroy the xdg_surface">
|
||||||
Destroy the xdg_surface object. An xdg_surface must only be destroyed
|
Destroy the xdg_surface object. An xdg_surface must only be destroyed
|
||||||
after its role object has been destroyed.
|
after its role object has been destroyed, otherwise
|
||||||
|
a defunct_role_object error is raised.
|
||||||
</description>
|
</description>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
@@ -489,8 +516,7 @@
|
|||||||
portions like drop-shadows which should be ignored for the
|
portions like drop-shadows which should be ignored for the
|
||||||
purposes of aligning, placing and constraining windows.
|
purposes of aligning, placing and constraining windows.
|
||||||
|
|
||||||
The window geometry is double buffered, and will be applied at the
|
The window geometry is double-buffered state, see wl_surface.commit.
|
||||||
time wl_surface.commit of the corresponding wl_surface is called.
|
|
||||||
|
|
||||||
When maintaining a position, the compositor should treat the (x, y)
|
When maintaining a position, the compositor should treat the (x, y)
|
||||||
coordinate of the window geometry as the top left corner of the window.
|
coordinate of the window geometry as the top left corner of the window.
|
||||||
@@ -506,13 +532,22 @@
|
|||||||
commit. This unset is meant for extremely simple clients.
|
commit. This unset is meant for extremely simple clients.
|
||||||
|
|
||||||
The arguments are given in the surface-local coordinate space of
|
The arguments are given in the surface-local coordinate space of
|
||||||
the wl_surface associated with this xdg_surface.
|
the wl_surface associated with this xdg_surface, and may extend outside
|
||||||
|
of the wl_surface itself to mark parts of the subsurface tree as part of
|
||||||
|
the window geometry.
|
||||||
|
|
||||||
The width and height must be greater than zero. Setting an invalid size
|
When applied, the effective window geometry will be the set window
|
||||||
will raise an error. When applied, the effective window geometry will be
|
geometry clamped to the bounding rectangle of the combined
|
||||||
the set window geometry clamped to the bounding rectangle of the
|
geometry of the surface of the xdg_surface and the associated
|
||||||
combined geometry of the surface of the xdg_surface and the associated
|
|
||||||
subsurfaces.
|
subsurfaces.
|
||||||
|
|
||||||
|
The effective geometry will not be recalculated unless a new call to
|
||||||
|
set_window_geometry is done and the new pending surface state is
|
||||||
|
subsequently applied.
|
||||||
|
|
||||||
|
The width and height of the effective window geometry must be
|
||||||
|
greater than zero. Setting an invalid size will raise an
|
||||||
|
invalid_size error.
|
||||||
</description>
|
</description>
|
||||||
<arg name="x" type="int"/>
|
<arg name="x" type="int"/>
|
||||||
<arg name="y" type="int"/>
|
<arg name="y" type="int"/>
|
||||||
@@ -533,6 +568,8 @@
|
|||||||
|
|
||||||
If the client receives multiple configure events before it
|
If the client receives multiple configure events before it
|
||||||
can respond to one, it only has to ack the last configure event.
|
can respond to one, it only has to ack the last configure event.
|
||||||
|
Acking a configure event that was never sent raises an invalid_serial
|
||||||
|
error.
|
||||||
|
|
||||||
A client is not required to commit immediately after sending
|
A client is not required to commit immediately after sending
|
||||||
an ack_configure request - it may even ack_configure several times
|
an ack_configure request - it may even ack_configure several times
|
||||||
@@ -541,6 +578,17 @@
|
|||||||
A client may send multiple ack_configure requests before committing, but
|
A client may send multiple ack_configure requests before committing, but
|
||||||
only the last request sent before a commit indicates which configure
|
only the last request sent before a commit indicates which configure
|
||||||
event the client really is responding to.
|
event the client really is responding to.
|
||||||
|
|
||||||
|
Sending an ack_configure request consumes the serial number sent with
|
||||||
|
the request, as well as serial numbers sent by all configure events
|
||||||
|
sent on this xdg_surface prior to the configure event referenced by
|
||||||
|
the committed serial.
|
||||||
|
|
||||||
|
It is an error to issue multiple ack_configure requests referencing a
|
||||||
|
serial from the same configure event, or to issue an ack_configure
|
||||||
|
request referencing a serial from a configure event issued before the
|
||||||
|
event identified by the last ack_configure request for the same
|
||||||
|
xdg_surface. Doing so will raise an invalid_serial error.
|
||||||
</description>
|
</description>
|
||||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||||
</request>
|
</request>
|
||||||
@@ -569,7 +617,7 @@
|
|||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="xdg_toplevel" version="3">
|
<interface name="xdg_toplevel" version="6">
|
||||||
<description summary="toplevel surface">
|
<description summary="toplevel surface">
|
||||||
This interface defines an xdg_surface role which allows a surface to,
|
This interface defines an xdg_surface role which allows a surface to,
|
||||||
among other things, set window-like properties such as maximize,
|
among other things, set window-like properties such as maximize,
|
||||||
@@ -577,11 +625,19 @@
|
|||||||
id, and well as trigger user interactive operations such as interactive
|
id, and well as trigger user interactive operations such as interactive
|
||||||
resize and move.
|
resize and move.
|
||||||
|
|
||||||
|
A xdg_toplevel by default is responsible for providing the full intended
|
||||||
|
visual representation of the toplevel, which depending on the window
|
||||||
|
state, may mean things like a title bar, window controls and drop shadow.
|
||||||
|
|
||||||
Unmapping an xdg_toplevel means that the surface cannot be shown
|
Unmapping an xdg_toplevel means that the surface cannot be shown
|
||||||
by the compositor until it is explicitly mapped again.
|
by the compositor until it is explicitly mapped again.
|
||||||
All active operations (e.g., move, resize) are canceled and all
|
All active operations (e.g., move, resize) are canceled and all
|
||||||
attributes (e.g. title, state, stacking, ...) are discarded for
|
attributes (e.g. title, state, stacking, ...) are discarded for
|
||||||
an xdg_toplevel surface when it is unmapped.
|
an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
|
||||||
|
the state it had right after xdg_surface.get_toplevel. The client
|
||||||
|
can re-map the toplevel by performing a commit without any buffer
|
||||||
|
attached, waiting for a configure event and handling it as usual (see
|
||||||
|
xdg_surface description).
|
||||||
|
|
||||||
Attaching a null buffer to a toplevel unmaps the surface.
|
Attaching a null buffer to a toplevel unmaps the surface.
|
||||||
</description>
|
</description>
|
||||||
@@ -593,24 +649,37 @@
|
|||||||
</description>
|
</description>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="invalid_resize_edge" value="0" summary="provided value is
|
||||||
|
not a valid variant of the resize_edge enum"/>
|
||||||
|
<entry name="invalid_parent" value="1"
|
||||||
|
summary="invalid parent toplevel"/>
|
||||||
|
<entry name="invalid_size" value="2"
|
||||||
|
summary="client provided an invalid min or max size"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
<request name="set_parent">
|
<request name="set_parent">
|
||||||
<description summary="set the parent of this surface">
|
<description summary="set the parent of this surface">
|
||||||
Set the "parent" of this surface. This surface should be stacked
|
Set the "parent" of this surface. This surface should be stacked
|
||||||
above the parent surface and all other ancestor surfaces.
|
above the parent surface and all other ancestor surfaces.
|
||||||
|
|
||||||
Parent windows should be set on dialogs, toolboxes, or other
|
Parent surfaces should be set on dialogs, toolboxes, or other
|
||||||
"auxiliary" surfaces, so that the parent is raised when the dialog
|
"auxiliary" surfaces, so that the parent is raised when the dialog
|
||||||
is raised.
|
is raised.
|
||||||
|
|
||||||
Setting a null parent for a child window removes any parent-child
|
Setting a null parent for a child surface unsets its parent. Setting
|
||||||
relationship for the child. Setting a null parent for a window which
|
a null parent for a surface which currently has no parent is a no-op.
|
||||||
currently has no parent is a no-op.
|
|
||||||
|
|
||||||
If the parent is unmapped then its children are managed as
|
Only mapped surfaces can have child surfaces. Setting a parent which
|
||||||
though the parent of the now-unmapped parent has become the
|
is not mapped is equivalent to setting a null parent. If a surface
|
||||||
parent of this surface. If no parent exists for the now-unmapped
|
becomes unmapped, its children's parent is set to the parent of
|
||||||
parent then the children are managed as though they have no
|
the now-unmapped surface. If the now-unmapped surface has no parent,
|
||||||
parent surface.
|
its children's parent is unset. If the now-unmapped surface becomes
|
||||||
|
mapped again, its parent-child relationship is not restored.
|
||||||
|
|
||||||
|
The parent toplevel must not be one of the child toplevel's
|
||||||
|
descendants, and the parent must be different from the child toplevel,
|
||||||
|
otherwise the invalid_parent protocol error is raised.
|
||||||
</description>
|
</description>
|
||||||
<arg name="parent" type="object" interface="xdg_toplevel" allow-null="true"/>
|
<arg name="parent" type="object" interface="xdg_toplevel" allow-null="true"/>
|
||||||
</request>
|
</request>
|
||||||
@@ -652,7 +721,7 @@
|
|||||||
application identifiers and how they relate to well-known D-Bus
|
application identifiers and how they relate to well-known D-Bus
|
||||||
names and .desktop files.
|
names and .desktop files.
|
||||||
|
|
||||||
[0] http://standards.freedesktop.org/desktop-entry-spec/
|
[0] https://standards.freedesktop.org/desktop-entry-spec/
|
||||||
</description>
|
</description>
|
||||||
<arg name="app_id" type="string"/>
|
<arg name="app_id" type="string"/>
|
||||||
</request>
|
</request>
|
||||||
@@ -666,7 +735,8 @@
|
|||||||
This request asks the compositor to pop up such a window menu at
|
This request asks the compositor to pop up such a window menu at
|
||||||
the given position, relative to the local surface coordinates of
|
the given position, relative to the local surface coordinates of
|
||||||
the parent surface. There are no guarantees as to what menu items
|
the parent surface. There are no guarantees as to what menu items
|
||||||
the window menu contains.
|
the window menu contains, or even if a window menu will be drawn
|
||||||
|
at all.
|
||||||
|
|
||||||
This request must be used in response to some sort of user action
|
This request must be used in response to some sort of user action
|
||||||
like a button press, key press, or touch down event.
|
like a button press, key press, or touch down event.
|
||||||
@@ -742,12 +812,13 @@
|
|||||||
guarantee that the device focus will return when the resize is
|
guarantee that the device focus will return when the resize is
|
||||||
completed.
|
completed.
|
||||||
|
|
||||||
The edges parameter specifies how the surface should be resized,
|
The edges parameter specifies how the surface should be resized, and
|
||||||
and is one of the values of the resize_edge enum. The compositor
|
is one of the values of the resize_edge enum. Values not matching
|
||||||
may use this information to update the surface position for
|
a variant of the enum will cause the invalid_resize_edge protocol error.
|
||||||
example when dragging the top left corner. The compositor may also
|
The compositor may use this information to update the surface position
|
||||||
use this information to adapt its behavior, e.g. choose an
|
for example when dragging the top left corner. The compositor may also
|
||||||
appropriate cursor image.
|
use this information to adapt its behavior, e.g. choose an appropriate
|
||||||
|
cursor image.
|
||||||
</description>
|
</description>
|
||||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
|
||||||
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
<arg name="serial" type="uint" summary="the serial of the user event"/>
|
||||||
@@ -761,13 +832,13 @@
|
|||||||
configure event to ensure that both the client and the compositor
|
configure event to ensure that both the client and the compositor
|
||||||
setting the state can be synchronized.
|
setting the state can be synchronized.
|
||||||
|
|
||||||
States set in this way are double-buffered. They will get applied on
|
States set in this way are double-buffered, see wl_surface.commit.
|
||||||
the next commit.
|
|
||||||
</description>
|
</description>
|
||||||
<entry name="maximized" value="1" summary="the surface is maximized">
|
<entry name="maximized" value="1" summary="the surface is maximized">
|
||||||
<description summary="the surface is maximized">
|
<description summary="the surface is maximized">
|
||||||
The surface is maximized. The window geometry specified in the configure
|
The surface is maximized. The window geometry specified in the configure
|
||||||
event must be obeyed by the client.
|
event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state
|
||||||
|
error is raised.
|
||||||
|
|
||||||
The client should draw without shadow or other
|
The client should draw without shadow or other
|
||||||
decoration outside of the window geometry.
|
decoration outside of the window geometry.
|
||||||
@@ -798,27 +869,46 @@
|
|||||||
</description>
|
</description>
|
||||||
</entry>
|
</entry>
|
||||||
<entry name="tiled_left" value="5" since="2">
|
<entry name="tiled_left" value="5" since="2">
|
||||||
<description summary="the surface is tiled">
|
<description summary="the surface’s left edge is tiled">
|
||||||
The window is currently in a tiled layout and the left edge is
|
The window is currently in a tiled layout and the left edge is
|
||||||
considered to be adjacent to another part of the tiling grid.
|
considered to be adjacent to another part of the tiling grid.
|
||||||
|
|
||||||
|
The client should draw without shadow or other decoration outside of
|
||||||
|
the window geometry on the left edge.
|
||||||
</description>
|
</description>
|
||||||
</entry>
|
</entry>
|
||||||
<entry name="tiled_right" value="6" since="2">
|
<entry name="tiled_right" value="6" since="2">
|
||||||
<description summary="the surface is tiled">
|
<description summary="the surface’s right edge is tiled">
|
||||||
The window is currently in a tiled layout and the right edge is
|
The window is currently in a tiled layout and the right edge is
|
||||||
considered to be adjacent to another part of the tiling grid.
|
considered to be adjacent to another part of the tiling grid.
|
||||||
|
|
||||||
|
The client should draw without shadow or other decoration outside of
|
||||||
|
the window geometry on the right edge.
|
||||||
</description>
|
</description>
|
||||||
</entry>
|
</entry>
|
||||||
<entry name="tiled_top" value="7" since="2">
|
<entry name="tiled_top" value="7" since="2">
|
||||||
<description summary="the surface is tiled">
|
<description summary="the surface’s top edge is tiled">
|
||||||
The window is currently in a tiled layout and the top edge is
|
The window is currently in a tiled layout and the top edge is
|
||||||
considered to be adjacent to another part of the tiling grid.
|
considered to be adjacent to another part of the tiling grid.
|
||||||
|
|
||||||
|
The client should draw without shadow or other decoration outside of
|
||||||
|
the window geometry on the top edge.
|
||||||
</description>
|
</description>
|
||||||
</entry>
|
</entry>
|
||||||
<entry name="tiled_bottom" value="8" since="2">
|
<entry name="tiled_bottom" value="8" since="2">
|
||||||
<description summary="the surface is tiled">
|
<description summary="the surface’s bottom edge is tiled">
|
||||||
The window is currently in a tiled layout and the bottom edge is
|
The window is currently in a tiled layout and the bottom edge is
|
||||||
considered to be adjacent to another part of the tiling grid.
|
considered to be adjacent to another part of the tiling grid.
|
||||||
|
|
||||||
|
The client should draw without shadow or other decoration outside of
|
||||||
|
the window geometry on the bottom edge.
|
||||||
|
</description>
|
||||||
|
</entry>
|
||||||
|
<entry name="suspended" value="9" since="6">
|
||||||
|
<description summary="surface repaint is suspended">
|
||||||
|
The surface is currently not ordinarily being repainted; for
|
||||||
|
example because its content is occluded by another window, or its
|
||||||
|
outputs are switched off due to screen locking.
|
||||||
</description>
|
</description>
|
||||||
</entry>
|
</entry>
|
||||||
</enum>
|
</enum>
|
||||||
@@ -833,8 +923,7 @@
|
|||||||
The width and height arguments are in window geometry coordinates.
|
The width and height arguments are in window geometry coordinates.
|
||||||
See xdg_surface.set_window_geometry.
|
See xdg_surface.set_window_geometry.
|
||||||
|
|
||||||
Values set in this way are double-buffered. They will get applied
|
Values set in this way are double-buffered, see wl_surface.commit.
|
||||||
on the next commit.
|
|
||||||
|
|
||||||
The compositor can use this information to allow or disallow
|
The compositor can use this information to allow or disallow
|
||||||
different states like maximize or fullscreen and draw accurate
|
different states like maximize or fullscreen and draw accurate
|
||||||
@@ -854,11 +943,11 @@
|
|||||||
request.
|
request.
|
||||||
|
|
||||||
Requesting a maximum size to be smaller than the minimum size of
|
Requesting a maximum size to be smaller than the minimum size of
|
||||||
a surface is illegal and will result in a protocol error.
|
a surface is illegal and will result in an invalid_size error.
|
||||||
|
|
||||||
The width and height must be greater than or equal to zero. Using
|
The width and height must be greater than or equal to zero. Using
|
||||||
strictly negative values for width and height will result in a
|
strictly negative values for width or height will result in a
|
||||||
protocol error.
|
invalid_size error.
|
||||||
</description>
|
</description>
|
||||||
<arg name="width" type="int"/>
|
<arg name="width" type="int"/>
|
||||||
<arg name="height" type="int"/>
|
<arg name="height" type="int"/>
|
||||||
@@ -874,8 +963,7 @@
|
|||||||
The width and height arguments are in window geometry coordinates.
|
The width and height arguments are in window geometry coordinates.
|
||||||
See xdg_surface.set_window_geometry.
|
See xdg_surface.set_window_geometry.
|
||||||
|
|
||||||
Values set in this way are double-buffered. They will get applied
|
Values set in this way are double-buffered, see wl_surface.commit.
|
||||||
on the next commit.
|
|
||||||
|
|
||||||
The compositor can use this information to allow or disallow
|
The compositor can use this information to allow or disallow
|
||||||
different states like maximize or fullscreen and draw accurate
|
different states like maximize or fullscreen and draw accurate
|
||||||
@@ -895,11 +983,11 @@
|
|||||||
request.
|
request.
|
||||||
|
|
||||||
Requesting a minimum size to be larger than the maximum size of
|
Requesting a minimum size to be larger than the maximum size of
|
||||||
a surface is illegal and will result in a protocol error.
|
a surface is illegal and will result in an invalid_size error.
|
||||||
|
|
||||||
The width and height must be greater than or equal to zero. Using
|
The width and height must be greater than or equal to zero. Using
|
||||||
strictly negative values for width and height will result in a
|
strictly negative values for width and height will result in a
|
||||||
protocol error.
|
invalid_size error.
|
||||||
</description>
|
</description>
|
||||||
<arg name="width" type="int"/>
|
<arg name="width" type="int"/>
|
||||||
<arg name="height" type="int"/>
|
<arg name="height" type="int"/>
|
||||||
@@ -1058,9 +1146,68 @@
|
|||||||
a dialog to ask the user to save their data, etc.
|
a dialog to ask the user to save their data, etc.
|
||||||
</description>
|
</description>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<!-- Version 4 additions -->
|
||||||
|
|
||||||
|
<event name="configure_bounds" since="4">
|
||||||
|
<description summary="recommended window geometry bounds">
|
||||||
|
The configure_bounds event may be sent prior to a xdg_toplevel.configure
|
||||||
|
event to communicate the bounds a window geometry size is recommended
|
||||||
|
to constrain to.
|
||||||
|
|
||||||
|
The passed width and height are in surface coordinate space. If width
|
||||||
|
and height are 0, it means bounds is unknown and equivalent to as if no
|
||||||
|
configure_bounds event was ever sent for this surface.
|
||||||
|
|
||||||
|
The bounds can for example correspond to the size of a monitor excluding
|
||||||
|
any panels or other shell components, so that a surface isn't created in
|
||||||
|
a way that it cannot fit.
|
||||||
|
|
||||||
|
The bounds may change at any point, and in such a case, a new
|
||||||
|
xdg_toplevel.configure_bounds will be sent, followed by
|
||||||
|
xdg_toplevel.configure and xdg_surface.configure.
|
||||||
|
</description>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Version 5 additions -->
|
||||||
|
|
||||||
|
<enum name="wm_capabilities" since="5">
|
||||||
|
<entry name="window_menu" value="1" summary="show_window_menu is available"/>
|
||||||
|
<entry name="maximize" value="2" summary="set_maximized and unset_maximized are available"/>
|
||||||
|
<entry name="fullscreen" value="3" summary="set_fullscreen and unset_fullscreen are available"/>
|
||||||
|
<entry name="minimize" value="4" summary="set_minimized is available"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="wm_capabilities" since="5">
|
||||||
|
<description summary="compositor capabilities">
|
||||||
|
This event advertises the capabilities supported by the compositor. If
|
||||||
|
a capability isn't supported, clients should hide or disable the UI
|
||||||
|
elements that expose this functionality. For instance, if the
|
||||||
|
compositor doesn't advertise support for minimized toplevels, a button
|
||||||
|
triggering the set_minimized request should not be displayed.
|
||||||
|
|
||||||
|
The compositor will ignore requests it doesn't support. For instance,
|
||||||
|
a compositor which doesn't advertise support for minimized will ignore
|
||||||
|
set_minimized requests.
|
||||||
|
|
||||||
|
Compositors must send this event once before the first
|
||||||
|
xdg_surface.configure event. When the capabilities change, compositors
|
||||||
|
must send this event again and then send an xdg_surface.configure
|
||||||
|
event.
|
||||||
|
|
||||||
|
The configured state should not be applied immediately. See
|
||||||
|
xdg_surface.configure for details.
|
||||||
|
|
||||||
|
The capabilities are sent as an array of 32-bit unsigned integers in
|
||||||
|
native endianness.
|
||||||
|
</description>
|
||||||
|
<arg name="capabilities" type="array" summary="array of 32-bit capabilities"/>
|
||||||
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="xdg_popup" version="3">
|
<interface name="xdg_popup" version="6">
|
||||||
<description summary="short-lived, popup surfaces for menus">
|
<description summary="short-lived, popup surfaces for menus">
|
||||||
A popup surface is a short-lived, temporary surface. It can be used to
|
A popup surface is a short-lived, temporary surface. It can be used to
|
||||||
implement for example menus, popovers, tooltips and other similar user
|
implement for example menus, popovers, tooltips and other similar user
|
||||||
@@ -1098,8 +1245,8 @@
|
|||||||
This destroys the popup. Explicitly destroying the xdg_popup
|
This destroys the popup. Explicitly destroying the xdg_popup
|
||||||
object will also dismiss the popup, and unmap the surface.
|
object will also dismiss the popup, and unmap the surface.
|
||||||
|
|
||||||
If this xdg_popup is not the "topmost" popup, a protocol error
|
If this xdg_popup is not the "topmost" popup, the
|
||||||
will be sent.
|
xdg_wm_base.not_the_topmost_popup protocol error will be sent.
|
||||||
</description>
|
</description>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
@@ -1131,10 +1278,6 @@
|
|||||||
nested grabbing popup as well. When a compositor dismisses popups, it
|
nested grabbing popup as well. When a compositor dismisses popups, it
|
||||||
will follow the same dismissing order as required from the client.
|
will follow the same dismissing order as required from the client.
|
||||||
|
|
||||||
The parent of a grabbing popup must either be another xdg_popup with an
|
|
||||||
active explicit grab, or an xdg_popup or xdg_toplevel, if there are no
|
|
||||||
explicit grabs already taken.
|
|
||||||
|
|
||||||
If the topmost grabbing popup is destroyed, the grab will be returned to
|
If the topmost grabbing popup is destroyed, the grab will be returned to
|
||||||
the parent of the popup, if that parent previously had an explicit grab.
|
the parent of the popup, if that parent previously had an explicit grab.
|
||||||
|
|
||||||
@@ -1204,12 +1347,12 @@
|
|||||||
|
|
||||||
If the popup is repositioned in response to a configure event for its
|
If the popup is repositioned in response to a configure event for its
|
||||||
parent, the client should send an xdg_positioner.set_parent_configure
|
parent, the client should send an xdg_positioner.set_parent_configure
|
||||||
and possibly a xdg_positioner.set_parent_size request to allow the
|
and possibly an xdg_positioner.set_parent_size request to allow the
|
||||||
compositor to properly constrain the popup.
|
compositor to properly constrain the popup.
|
||||||
|
|
||||||
If the popup is repositioned together with a parent that is being
|
If the popup is repositioned together with a parent that is being
|
||||||
resized, but not in response to a configure event, the client should
|
resized, but not in response to a configure event, the client should
|
||||||
send a xdg_positioner.set_parent_size request.
|
send an xdg_positioner.set_parent_size request.
|
||||||
</description>
|
</description>
|
||||||
<arg name="positioner" type="object" interface="xdg_positioner"/>
|
<arg name="positioner" type="object" interface="xdg_positioner"/>
|
||||||
<arg name="token" type="uint" summary="reposition request token"/>
|
<arg name="token" type="uint" summary="reposition request token"/>
|
||||||
|
|||||||
Reference in new issue
Block a user